Index: chrome/browser/crash_handler_host_linux.cc |
=================================================================== |
--- chrome/browser/crash_handler_host_linux.cc (revision 88621) |
+++ chrome/browser/crash_handler_host_linux.cc (working copy) |
@@ -221,11 +221,12 @@ |
return; |
} |
- // Kernel bug workaround (broken in 2.6.30 at least): |
+ // Kernel bug workaround (broken in 2.6.30 and 2.6.32, working in 2.6.38). |
// The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID |
// namespaces. Thus |crashing_pid| might be garbage from our point of view. |
// In the future we can remove this workaround, but we have to wait a couple |
// of years to be sure that it's worked its way out into the world. |
+ // TODO(thestig) Remove the workaround when Ubuntu Lucid is deprecated. |
// The crashing process closes its copy of the signal_fd immediately after |
// calling sendmsg(). We can thus not reliably look for with with |
@@ -248,40 +249,44 @@ |
return; |
} |
- if (actual_crashing_pid != crashing_pid) { |
- crashing_pid = actual_crashing_pid; |
+ crashing_pid = actual_crashing_pid; |
- // The crashing TID set inside the compromised context via sys_gettid() |
- // in ExceptionHandler::HandleSignal is also wrong and needs to be |
- // translated. |
- // |
- // We expect the crashing thread to be in sys_read(), waiting for use to |
- // write to |signal_fd|. Most newer kernels where we have the different pid |
- // namespaces also have /proc/[pid]/syscall, so we can look through |
- // |actual_crashing_pid|'s thread group and find the thread that's in the |
- // read syscall with the right arguments. |
+ // The crashing TID set inside the compromised context via |
+ // sys_gettid() in ExceptionHandler::HandleSignal might be wrong (if |
+ // the kernel supports PID namespacing) and may need to be |
+ // translated. |
+ // |
+ // We expect the crashing thread to be in sys_read(), waiting for us to |
+ // write to |signal_fd|. Most newer kernels where we have the different pid |
+ // namespaces also have /proc/[pid]/syscall, so we can look through |
+ // |actual_crashing_pid|'s thread group and find the thread that's in the |
+ // read syscall with the right arguments. |
- std::string expected_syscall_data; |
- // /proc/[pid]/syscall is formatted as follows: |
- // syscall_number arg1 ... arg6 sp pc |
- // but we just check syscall_number through arg3. |
- base::StringAppendF(&expected_syscall_data, "%d 0x%x %p 0x1 ", |
- SYS_read, tid_fd, tid_buf_addr); |
- pid_t crashing_tid = |
- base::FindThreadIDWithSyscall(crashing_pid, expected_syscall_data); |
- if (crashing_tid == -1) { |
- // We didn't find the thread we want. Maybe it didn't reach sys_read() |
- // yet, or the kernel doesn't support /proc/[pid]/syscall or the thread |
- // went away. We'll just take a guess here and assume the crashing |
- // thread is the thread group leader. |
- crashing_tid = crashing_pid; |
- } |
- |
- ExceptionHandler::CrashContext* bad_context = |
- reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context); |
- bad_context->tid = crashing_tid; |
+ std::string expected_syscall_data; |
+ // /proc/[pid]/syscall is formatted as follows: |
+ // syscall_number arg1 ... arg6 sp pc |
+ // but we just check syscall_number through arg3. |
+ base::StringAppendF(&expected_syscall_data, "%d 0x%x %p 0x1 ", |
+ SYS_read, tid_fd, tid_buf_addr); |
+ bool syscall_supported = false; |
+ pid_t crashing_tid = |
+ base::FindThreadIDWithSyscall(crashing_pid, |
+ expected_syscall_data, |
+ &syscall_supported); |
+ if (crashing_tid == -1 && syscall_supported) { |
+ // We didn't find the thread we want. Maybe it didn't reach |
+ // sys_read() yet or the thread went away. We'll just take a |
+ // guess here and assume the crashing thread is the thread group |
+ // leader. If procfs syscall is not supported by the kernel, then |
+ // we assume the kernel also does not support TID namespacing and |
+ // trust the TID passed by the crashing process. |
+ crashing_tid = crashing_pid; |
} |
+ ExceptionHandler::CrashContext* bad_context = |
+ reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context); |
+ bad_context->tid = crashing_tid; |
+ |
// Sanitize the string data a bit more |
guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; |