OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <fcntl.h> | 5 #include <fcntl.h> |
6 #include <sys/socket.h> | 6 #include <sys/socket.h> |
7 #include <sys/uio.h> | 7 #include <sys/uio.h> |
8 #include <unistd.h> | 8 #include <unistd.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 // report. | 472 // report. |
473 namespace renderer_logging { | 473 namespace renderer_logging { |
474 extern std::string active_url; | 474 extern std::string active_url; |
475 } | 475 } |
476 | 476 |
477 static bool | 477 static bool |
478 RendererCrashHandler(const void* crash_context, size_t crash_context_size, | 478 RendererCrashHandler(const void* crash_context, size_t crash_context_size, |
479 void* context) { | 479 void* context) { |
480 const int fd = (int) context; | 480 const int fd = (int) context; |
481 int fds[2]; | 481 int fds[2]; |
482 pipe(fds); | 482 socketpair(AF_UNIX, SOCK_STREAM, 0, fds); |
483 | 483 |
484 // The length of the control message: | 484 // The length of the control message: |
485 static const unsigned kControlMsgSize = | 485 static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); |
486 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); | |
487 | 486 |
488 union { | 487 struct kernel_msghdr msg; |
489 struct kernel_msghdr msg; | |
490 struct msghdr sys_msg; | |
491 }; | |
492 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); | 488 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); |
493 struct kernel_iovec iov[3]; | 489 struct kernel_iovec iov[3]; |
494 iov[0].iov_base = const_cast<void*>(crash_context); | 490 iov[0].iov_base = const_cast<void*>(crash_context); |
495 iov[0].iov_len = crash_context_size; | 491 iov[0].iov_len = crash_context_size; |
496 iov[1].iov_base = const_cast<char*>(google_update::linux_guid.data()); | 492 iov[1].iov_base = const_cast<char*>(google_update::linux_guid.data()); |
497 iov[1].iov_len = google_update::linux_guid.size(); | 493 iov[1].iov_len = google_update::linux_guid.size(); |
498 iov[2].iov_base = const_cast<char*>(renderer_logging::active_url.data()); | 494 iov[2].iov_base = const_cast<char*>(renderer_logging::active_url.data()); |
499 iov[2].iov_len = renderer_logging::active_url.size(); | 495 iov[2].iov_len = renderer_logging::active_url.size(); |
500 | 496 |
501 msg.msg_iov = iov; | 497 msg.msg_iov = iov; |
502 msg.msg_iovlen = 3; | 498 msg.msg_iovlen = 3; |
503 char cmsg[kControlMsgSize]; | 499 char cmsg[kControlMsgSize]; |
504 memset(cmsg, 0, kControlMsgSize); | 500 memset(cmsg, 0, kControlMsgSize); |
505 msg.msg_control = cmsg; | 501 msg.msg_control = cmsg; |
506 msg.msg_controllen = sizeof(cmsg); | 502 msg.msg_controllen = sizeof(cmsg); |
507 | 503 |
508 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); | 504 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); |
509 hdr->cmsg_level = SOL_SOCKET; | 505 hdr->cmsg_level = SOL_SOCKET; |
510 hdr->cmsg_type = SCM_RIGHTS; | 506 hdr->cmsg_type = SCM_RIGHTS; |
511 hdr->cmsg_len = CMSG_LEN(sizeof(int)); | 507 hdr->cmsg_len = CMSG_LEN(sizeof(int)); |
512 *((int*) CMSG_DATA(hdr)) = fds[1]; | 508 *((int*) CMSG_DATA(hdr)) = fds[1]; |
513 hdr = CMSG_NXTHDR(&sys_msg, hdr); | |
514 hdr->cmsg_level = SOL_SOCKET; | |
515 hdr->cmsg_type = SCM_CREDENTIALS; | |
516 hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred)); | |
517 struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr)); | |
518 cred->uid = getuid(); | |
519 cred->gid = getgid(); | |
520 cred->pid = getpid(); | |
521 | 509 |
522 HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)); | 510 HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)); |
523 sys_close(fds[1]); | 511 sys_close(fds[1]); |
524 | 512 |
525 char b; | 513 char b; |
526 HANDLE_EINTR(sys_read(fds[0], &b, 1)); | 514 HANDLE_EINTR(sys_read(fds[0], &b, 1)); |
527 | 515 |
528 return true; | 516 return true; |
529 } | 517 } |
530 | 518 |
531 void EnableRendererCrashDumping() { | 519 void EnableRendererCrashDumping() { |
532 const int fd = Singleton<base::GlobalDescriptors>()->Get(kCrashDumpSignal); | 520 const int fd = Singleton<base::GlobalDescriptors>()->Get(kCrashDumpSignal); |
533 // We deliberately leak this object. | 521 // We deliberately leak this object. |
534 google_breakpad::ExceptionHandler* handler = | 522 google_breakpad::ExceptionHandler* handler = |
535 new google_breakpad::ExceptionHandler("" /* unused */, NULL, NULL, | 523 new google_breakpad::ExceptionHandler("" /* unused */, NULL, NULL, |
536 (void*) fd, true); | 524 (void*) fd, true); |
537 handler->set_crash_handler(RendererCrashHandler); | 525 handler->set_crash_handler(RendererCrashHandler); |
538 } | 526 } |
539 | 527 |
540 void InitCrashReporter() { | 528 void InitCrashReporter() { |
541 if (!GoogleUpdateSettings::GetCollectStatsConsent()) | |
542 return; | |
543 | |
544 // Determine the process type and take appropriate action. | 529 // Determine the process type and take appropriate action. |
545 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 530 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
546 const std::wstring process_type = | 531 const std::wstring process_type = |
547 parsed_command_line.GetSwitchValue(switches::kProcessType); | 532 parsed_command_line.GetSwitchValue(switches::kProcessType); |
548 if (process_type.empty()) { | 533 if (process_type.empty()) { |
| 534 if (!GoogleUpdateSettings::GetCollectStatsConsent()) |
| 535 return; |
549 EnableCrashDumping(); | 536 EnableCrashDumping(); |
550 } else if (process_type == switches::kRendererProcess || | 537 } else if (process_type == switches::kRendererProcess || |
551 process_type == switches::kZygoteProcess) { | 538 process_type == switches::kZygoteProcess) { |
| 539 // We might be chrooted in a zygote or renderer process so we cannot call |
| 540 // GetCollectStatsConsent because that needs access the the user's home |
| 541 // dir. Instead, we set a command line flag for these processes. |
| 542 if (!parsed_command_line.HasSwitch(switches::kRendererCrashDump)) |
| 543 return; |
552 EnableRendererCrashDumping(); | 544 EnableRendererCrashDumping(); |
553 } | 545 } |
554 } | 546 } |
OLD | NEW |