| 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 |