Chromium Code Reviews| Index: base/debug/proc_maps_linux.cc |
| diff --git a/base/debug/proc_maps_linux.cc b/base/debug/proc_maps_linux.cc |
| index 9557feb025994b1e88763b3c52f855127eaeda81..7257b4ac8197a2d0dfe10339f8b417ec1c1a62d1 100644 |
| --- a/base/debug/proc_maps_linux.cc |
| +++ b/base/debug/proc_maps_linux.cc |
| @@ -4,6 +4,8 @@ |
| #include "base/debug/proc_maps_linux.h" |
| +#include <fcntl.h> |
| + |
| #if defined(OS_LINUX) |
| #include <inttypes.h> |
| #endif |
| @@ -22,9 +24,50 @@ |
| namespace base { |
| namespace debug { |
| +// Local testing revealed that the size of /proc/<pid>/maps for an official |
| +// release build of chrome hovered around the ~45 KB mark with some processes |
| +// hitting 80-90 KB. |
| +// |
| +// We'll play it safe and use 1 MB. |
| +enum { kMaxProcMapsSize = 1024 * 1024 }; |
| + |
| bool ReadProcMaps(std::string* proc_maps) { |
| - FilePath proc_maps_path("/proc/self/maps"); |
| - return file_util::ReadFileToString(proc_maps_path, proc_maps); |
| + scoped_ptr<char[]> buffer(new char[kMaxProcMapsSize]); |
| + |
| + int fd = HANDLE_EINTR(open("/proc/self/maps", O_RDONLY)); |
| + if (fd == -1) { |
| + DPLOG(ERROR) << "Couldn't open /proc/self/maps"; |
| + return false; |
| + } |
| + file_util::ScopedFD fd_closer(&fd); |
| + |
| + // XXX there's file_util::ReadFromFD() but it expects an exact # of bytes |
| + // to be read whereas here we're reading until EOF. Perhaps we can change |
| + // the API / add a new one / add an optional param? |
| + ssize_t offset = 0; |
| + while (true) { |
| + ssize_t bytes_read = HANDLE_EINTR( |
| + read(fd, buffer.get() + offset, kMaxProcMapsSize - offset)); |
|
Alexander Potapenko
2013/07/11 10:47:23
There must be only one read() call, otherwise we'r
|
| + if (bytes_read < 0) { |
| + DPLOG(ERROR) << "Couldn't read /proc/self/maps"; |
| + return false; |
| + } |
| + |
| + offset += bytes_read; |
| + if (offset == kMaxProcMapsSize) { |
| + DLOG(ERROR) << "/proc/self/maps is too large"; |
| + return false; |
| + } |
| + |
| + if (bytes_read == 0) |
| + break; |
| + } |
| + |
| + // Use 2-arg version of assign() to avoid an unnecessary length computation |
| + // of |buffer|. |
| + buffer[offset] = '\0'; |
| + proc_maps->assign(buffer.get(), offset); |
| + return true; |
| } |
| bool ParseProcMaps(const std::string& input, |