Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Side by Side Diff: chrome/browser/crash_handler_host_linux.cc

Issue 7190019: Always search TIDs for the crashing processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/linux_util.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/crash_handler_host_linux.h" 5 #include "chrome/browser/crash_handler_host_linux.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/syscall.h> 10 #include <sys/syscall.h>
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 if (crashing_pid == -1 || partner_fd == -1 || signal_fd == -1) { 214 if (crashing_pid == -1 || partner_fd == -1 || signal_fd == -1) {
215 LOG(ERROR) << "Death signal message didn't contain all expected control" 215 LOG(ERROR) << "Death signal message didn't contain all expected control"
216 << " messages"; 216 << " messages";
217 if (partner_fd >= 0) 217 if (partner_fd >= 0)
218 HANDLE_EINTR(close(partner_fd)); 218 HANDLE_EINTR(close(partner_fd));
219 if (signal_fd >= 0) 219 if (signal_fd >= 0)
220 HANDLE_EINTR(close(signal_fd)); 220 HANDLE_EINTR(close(signal_fd));
221 return; 221 return;
222 } 222 }
223 223
224 // Kernel bug workaround (broken in 2.6.30 at least): 224 // Kernel bug workaround (broken in 2.6.30 at least):
Lei Zhang 2011/06/20 21:37:10 Can we update this comment block to: // Kernel bu
kmixter1 2011/06/20 23:49:17 Done.
225 // The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID 225 // The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID
226 // namespaces. Thus |crashing_pid| might be garbage from our point of view. 226 // namespaces. Thus |crashing_pid| might be garbage from our point of view.
227 // In the future we can remove this workaround, but we have to wait a couple 227 // In the future we can remove this workaround, but we have to wait a couple
228 // of years to be sure that it's worked its way out into the world. 228 // of years to be sure that it's worked its way out into the world.
229 229
230 // The crashing process closes its copy of the signal_fd immediately after 230 // The crashing process closes its copy of the signal_fd immediately after
231 // calling sendmsg(). We can thus not reliably look for with with 231 // calling sendmsg(). We can thus not reliably look for with with
232 // FindProcessHoldingSocket(). But by necessity, it has to keep the 232 // FindProcessHoldingSocket(). But by necessity, it has to keep the
233 // partner_fd open until the crashdump is complete. 233 // partner_fd open until the crashdump is complete.
234 uint64_t inode_number; 234 uint64_t inode_number;
235 if (!base::FileDescriptorGetInode(&inode_number, partner_fd)) { 235 if (!base::FileDescriptorGetInode(&inode_number, partner_fd)) {
236 LOG(WARNING) << "Failed to get inode number for passed socket"; 236 LOG(WARNING) << "Failed to get inode number for passed socket";
237 HANDLE_EINTR(close(partner_fd)); 237 HANDLE_EINTR(close(partner_fd));
238 HANDLE_EINTR(close(signal_fd)); 238 HANDLE_EINTR(close(signal_fd));
239 return; 239 return;
240 } 240 }
241 HANDLE_EINTR(close(partner_fd)); 241 HANDLE_EINTR(close(partner_fd));
242 242
243 pid_t actual_crashing_pid = -1; 243 pid_t actual_crashing_pid = -1;
244 if (!base::FindProcessHoldingSocket(&actual_crashing_pid, inode_number)) { 244 if (!base::FindProcessHoldingSocket(&actual_crashing_pid, inode_number)) {
245 LOG(WARNING) << "Failed to find process holding other end of crash reply " 245 LOG(WARNING) << "Failed to find process holding other end of crash reply "
246 "socket"; 246 "socket";
247 HANDLE_EINTR(close(signal_fd)); 247 HANDLE_EINTR(close(signal_fd));
248 return; 248 return;
249 } 249 }
250 250
251 if (actual_crashing_pid != crashing_pid) { 251 crashing_pid = actual_crashing_pid;
252 crashing_pid = actual_crashing_pid;
253 252
254 // The crashing TID set inside the compromised context via sys_gettid() 253 // The crashing TID set inside the compromised context via sys_gettid()
255 // in ExceptionHandler::HandleSignal is also wrong and needs to be 254 // in ExceptionHandler::HandleSignal is also wrong and needs to be
Lei Zhang 2011/06/20 21:37:10 s/is also/might be/
kmixter1 2011/06/20 23:49:17 Done.
256 // translated. 255 // translated.
257 // 256 //
258 // We expect the crashing thread to be in sys_read(), waiting for use to 257 // We expect the crashing thread to be in sys_read(), waiting for use to
259 // write to |signal_fd|. Most newer kernels where we have the different pid 258 // write to |signal_fd|. Most newer kernels where we have the different pid
260 // namespaces also have /proc/[pid]/syscall, so we can look through 259 // namespaces also have /proc/[pid]/syscall, so we can look through
261 // |actual_crashing_pid|'s thread group and find the thread that's in the 260 // |actual_crashing_pid|'s thread group and find the thread that's in the
262 // read syscall with the right arguments. 261 // read syscall with the right arguments.
263 262
264 std::string expected_syscall_data; 263 std::string expected_syscall_data;
265 // /proc/[pid]/syscall is formatted as follows: 264 // /proc/[pid]/syscall is formatted as follows:
266 // syscall_number arg1 ... arg6 sp pc 265 // syscall_number arg1 ... arg6 sp pc
267 // but we just check syscall_number through arg3. 266 // but we just check syscall_number through arg3.
268 base::StringAppendF(&expected_syscall_data, "%d 0x%x %p 0x1 ", 267 base::StringAppendF(&expected_syscall_data, "%d 0x%x %p 0x1 ",
269 SYS_read, tid_fd, tid_buf_addr); 268 SYS_read, tid_fd, tid_buf_addr);
270 pid_t crashing_tid = 269 bool syscall_supported = false;
271 base::FindThreadIDWithSyscall(crashing_pid, expected_syscall_data); 270 pid_t crashing_tid =
272 if (crashing_tid == -1) { 271 base::FindThreadIDWithSyscall(crashing_pid,
273 // We didn't find the thread we want. Maybe it didn't reach sys_read() 272 expected_syscall_data,
274 // yet, or the kernel doesn't support /proc/[pid]/syscall or the thread 273 &syscall_supported);
275 // went away. We'll just take a guess here and assume the crashing 274 if (crashing_tid == -1 && syscall_supported) {
276 // thread is the thread group leader. 275 // We didn't find the thread we want. Maybe it didn't reach
277 crashing_tid = crashing_pid; 276 // sys_read() yet or the thread went away. We'll just take a
278 } 277 // guess here and assume the crashing thread is the thread group
278 // leader. If procfs syscall is not supported by the kernel, then
279 // we assume the kernel also does not support TID namespacing and
280 // trust the TID passed by the crashing process.
281 crashing_tid = crashing_pid;
282 }
279 283
280 ExceptionHandler::CrashContext* bad_context = 284 ExceptionHandler::CrashContext* bad_context =
281 reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context); 285 reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context);
282 bad_context->tid = crashing_tid; 286 bad_context->tid = crashing_tid;
283 }
284 287
285 // Sanitize the string data a bit more 288 // Sanitize the string data a bit more
286 guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; 289 guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0;
287 290
288 // Freed in CrashDumpTask(); 291 // Freed in CrashDumpTask();
289 BreakpadInfo* info = new BreakpadInfo; 292 BreakpadInfo* info = new BreakpadInfo;
290 293
291 info->process_type_length = process_type_.length(); 294 info->process_type_length = process_type_.length();
292 char* process_type_str = new char[info->process_type_length + 1]; 295 char* process_type_str = new char[info->process_type_length + 1];
293 process_type_.copy(process_type_str, info->process_type_length); 296 process_type_.copy(process_type_str, info->process_type_length);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 443 }
441 444
442 void PpapiCrashHandlerHostLinux::SetProcessType() { 445 void PpapiCrashHandlerHostLinux::SetProcessType() {
443 process_type_ = "ppapi"; 446 process_type_ = "ppapi";
444 } 447 }
445 448
446 // static 449 // static
447 PpapiCrashHandlerHostLinux* PpapiCrashHandlerHostLinux::GetInstance() { 450 PpapiCrashHandlerHostLinux* PpapiCrashHandlerHostLinux::GetInstance() {
448 return Singleton<PpapiCrashHandlerHostLinux>::get(); 451 return Singleton<PpapiCrashHandlerHostLinux>::get();
449 } 452 }
OLDNEW
« no previous file with comments | « base/linux_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698