Chromium Code Reviews| Index: base/memory/shared_memory_helper.cc |
| diff --git a/base/memory/shared_memory_helper.cc b/base/memory/shared_memory_helper.cc |
| index e80083cf78d4e26550c6c9ff99b48f12e8087d1b..4f7c3b5a2058f36269ce3792b7b88d4cc64c17a4 100644 |
| --- a/base/memory/shared_memory_helper.cc |
| +++ b/base/memory/shared_memory_helper.cc |
| @@ -4,6 +4,13 @@ |
| #include "base/memory/shared_memory_helper.h" |
| +#if defined(OS_CHROMEOS) |
| +#include <sys/resource.h> |
| +#include <sys/time.h> |
| + |
| +#include "base/debug/alias.h" |
| +#endif // defined(OS_CHROMEOS) |
| + |
| #include "base/threading/thread_restrictions.h" |
| namespace base { |
| @@ -90,6 +97,55 @@ bool PrepareMapFile(ScopedFILE fp, |
| *mapped_file = HANDLE_EINTR(dup(fileno(fp.get()))); |
| if (*mapped_file == -1) { |
| NOTREACHED() << "Call to dup failed, errno=" << errno; |
| +#if defined(OS_CHROMEOS) |
| + if (errno == EMFILE) { |
| + // We're out of file descriptors and are probably about to crash somewhere |
| + // else in Chrome anyway. Let's collect what FD information we can and |
| + // crash. |
| + // Added for debugging crbug.com/733718 |
| + struct rlimit rlim; |
| + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { |
| + if (rlim.rlim_max > rlim.rlim_cur) { |
| + // Increase fd limit so breakpad has a chance to write a minidump. |
| + rlim.rlim_cur = rlim.rlim_max; |
| + if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { |
| + PLOG(ERROR) << "setrlimit() failed"; |
| + } |
| + } |
| + } else { |
| + PLOG(ERROR) << "getrlimit() failed"; |
| + // Fall back to 16K if we can't call getrlimit(). |
| + rlim.rlim_cur = 16384; |
| + } |
| + |
| + static const char* kFileDataMarker = "FDATA"; |
|
Lei Zhang
2017/06/29 22:06:29
Can this be trully const as const char kFileDataMa
teravest
2017/06/29 22:17:44
Done.
|
| + char buf[PATH_MAX]; |
|
Lei Zhang
2017/06/29 22:06:29
Declare |buf| and |fd_path| closer to where they a
teravest
2017/06/29 22:17:44
This is gross, but I want crash_buffer to be as cl
|
| + char fd_path[PATH_MAX]; |
| + char crash_buffer[2 * 1024 * 1024]; // 2M |
| + char *crash_ptr = crash_buffer; |
| + memset(crash_buffer, 0, arraysize(crash_buffer)); |
| + base::debug::Alias(crash_buffer); |
| + |
| + // Put a marker at the start of our data so we can confirm where it |
| + // begins. |
| + crash_ptr = strncpy(crash_ptr, kFileDataMarker, strlen(kFileDataMarker)); |
| + for (int i = 0; i < static_cast<int>(rlim.rlim_cur); i++) { |
| + memset(buf, 0, arraysize(buf)); |
| + memset(fd_path, 0, arraysize(fd_path)); |
| + sprintf(fd_path, "/proc/self/fd/%d", i, arraysize(fd_path) - 1); |
|
Lei Zhang
2017/06/29 22:06:29
Did you mean to use snprintf() here? I only see "%
teravest
2017/06/29 22:17:44
Fixed.
|
| + ssize_t count = readlink(fd_path, buf, arraysize(buf) - 1); |
|
Lei Zhang
2017/06/29 22:06:28
Do you care if readlink() fails and returns -1?
teravest
2017/06/29 22:17:44
Hmm. Probably not, but I'll add a log anyway.
|
| + |
| + if (crash_ptr + count + 1 < crash_buffer + arraysize(crash_buffer)) { |
| + crash_ptr = strncpy(crash_ptr, buf, count + 1); |
| + } |
| + |
| + if (count >= 0) { |
| + LOG(ERROR) << i << ": " << buf; |
| + } |
| + } |
| + CHECK(false) << "Logged for file descriptor exhaustion, crashing now"; |
|
Lei Zhang
2017/06/29 22:06:29
super nitty: I like LOG(FATAL) better when it's ac
teravest
2017/06/29 22:17:44
Done.
|
| + } |
| +#endif // defined(OS_CHROMEOS) |
| } |
| *readonly_mapped_file = readonly_fd.release(); |