OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #define SYS_SEGMENTNAME "syscalls" // For linux_syscall_support.h | 5 #define SYS_SEGMENTNAME "syscalls" // For linux_syscall_support.h |
6 | 6 |
7 #include "chrome/app/breakpad_linux.h" | 7 #include "chrome/app/breakpad_linux.h" |
8 | 8 |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <stdlib.h> | 10 #include <stdlib.h> |
11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
12 #include <sys/time.h> | 12 #include <sys/time.h> |
13 #include <sys/types.h> | 13 #include <sys/types.h> |
14 #include <sys/uio.h> | 14 #include <sys/uio.h> |
15 #include <time.h> | 15 #include <time.h> |
16 #include <unistd.h> | 16 #include <unistd.h> |
17 | 17 |
18 #include <algorithm> | 18 #include <algorithm> |
19 #include <string> | 19 #include <string> |
20 | 20 |
21 #include "base/command_line.h" | 21 #include "base/command_line.h" |
22 #include "base/eintr_wrapper.h" | 22 #include "base/eintr_wrapper.h" |
23 #include "base/file_path.h" | 23 #include "base/file_path.h" |
24 #include "base/global_descriptors_posix.h" | 24 #include "base/global_descriptors_posix.h" |
| 25 #include "base/linux_util.h" |
25 #include "base/path_service.h" | 26 #include "base/path_service.h" |
26 #include "base/string_util.h" | 27 #include "base/string_util.h" |
27 #include "breakpad/src/client/linux/handler/exception_handler.h" | 28 #include "breakpad/src/client/linux/handler/exception_handler.h" |
28 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" | 29 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" |
29 #include "breakpad/src/common/linux/linux_libc_support.h" | 30 #include "breakpad/src/common/linux/linux_libc_support.h" |
30 #include "breakpad/src/common/linux/linux_syscall_support.h" | 31 #include "breakpad/src/common/linux/linux_syscall_support.h" |
31 #include "breakpad/src/common/linux/memory.h" | 32 #include "breakpad/src/common/linux/memory.h" |
| 33 #include "chrome/common/child_process_logging.h" |
32 #include "chrome/common/chrome_descriptors.h" | 34 #include "chrome/common/chrome_descriptors.h" |
33 #include "chrome/common/chrome_paths.h" | 35 #include "chrome/common/chrome_paths.h" |
34 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
35 #include "chrome/common/chrome_version_info_posix.h" | 37 #include "chrome/common/chrome_version_info_posix.h" |
36 #include "chrome/common/env_vars.h" | 38 #include "chrome/common/env_vars.h" |
37 #include "chrome/installer/util/google_update_settings.h" | |
38 | 39 |
39 // Some versions of gcc are prone to warn about unused return values. In cases | 40 // Some versions of gcc are prone to warn about unused return values. In cases |
40 // where we either a) know the call cannot fail, or b) there is nothing we | 41 // where we either a) know the call cannot fail, or b) there is nothing we |
41 // can do when a call fails, we mark the return code as ignored. This avoids | 42 // can do when a call fails, we mark the return code as ignored. This avoids |
42 // spurious compiler warnings. | 43 // spurious compiler warnings. |
43 #define IGNORE_RET(x) do { if (x); } while (0) | 44 #define IGNORE_RET(x) do { if (x); } while (0) |
44 | 45 |
45 static const char kUploadURL[] = | 46 static const char kUploadURL[] = |
46 "https://clients2.google.com/cr/report"; | 47 "https://clients2.google.com/cr/report"; |
47 | 48 |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 static const char msg[] = "Cannot upload crash dump: cannot exec " | 573 static const char msg[] = "Cannot upload crash dump: cannot exec " |
573 "/usr/bin/wget\n"; | 574 "/usr/bin/wget\n"; |
574 sys_write(2, msg, sizeof(msg) - 1); | 575 sys_write(2, msg, sizeof(msg) - 1); |
575 sys__exit(1); | 576 sys__exit(1); |
576 } | 577 } |
577 | 578 |
578 HANDLE_EINTR(sys_waitpid(child, NULL, 0)); | 579 HANDLE_EINTR(sys_waitpid(child, NULL, 0)); |
579 return child; | 580 return child; |
580 } | 581 } |
581 | 582 |
582 // This is defined in chrome/browser/google_update_settings_posix.cc, it's the | |
583 // static string containing the user's unique GUID. We send this in the crash | |
584 // report. | |
585 namespace google_update { | |
586 extern std::string posix_guid; | |
587 } | |
588 | |
589 // This is defined in base/linux_util.cc, it's the static string containing the | |
590 // user's distro info. We send this in the crash report. | |
591 namespace base { | |
592 extern std::string linux_distro; | |
593 } | |
594 | |
595 static bool CrashDone(const char* dump_path, | 583 static bool CrashDone(const char* dump_path, |
596 const char* minidump_id, | 584 const char* minidump_id, |
597 const bool upload, | 585 const bool upload, |
598 const bool succeeded) { | 586 const bool succeeded) { |
599 // WARNING: this code runs in a compromised context. It may not call into | 587 // WARNING: this code runs in a compromised context. It may not call into |
600 // libc nor allocate memory normally. | 588 // libc nor allocate memory normally. |
601 if (!succeeded) | 589 if (!succeeded) |
602 return false; | 590 return false; |
603 | 591 |
604 google_breakpad::PageAllocator allocator; | 592 google_breakpad::PageAllocator allocator; |
605 const unsigned dump_path_len = my_strlen(dump_path); | 593 const unsigned dump_path_len = my_strlen(dump_path); |
606 const unsigned minidump_id_len = my_strlen(minidump_id); | 594 const unsigned minidump_id_len = my_strlen(minidump_id); |
607 char *const path = reinterpret_cast<char*>(allocator.Alloc( | 595 char *const path = reinterpret_cast<char*>(allocator.Alloc( |
608 dump_path_len + 1 /* '/' */ + minidump_id_len + | 596 dump_path_len + 1 /* '/' */ + minidump_id_len + |
609 4 /* ".dmp" */ + 1 /* NUL */)); | 597 4 /* ".dmp" */ + 1 /* NUL */)); |
610 memcpy(path, dump_path, dump_path_len); | 598 memcpy(path, dump_path, dump_path_len); |
611 path[dump_path_len] = '/'; | 599 path[dump_path_len] = '/'; |
612 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); | 600 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); |
613 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); | 601 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); |
614 path[dump_path_len + 1 + minidump_id_len + 4] = 0; | 602 path[dump_path_len + 1 + minidump_id_len + 4] = 0; |
615 | 603 |
616 BreakpadInfo info; | 604 BreakpadInfo info; |
617 info.filename = path; | 605 info.filename = path; |
618 info.process_type = "browser"; | 606 info.process_type = "browser"; |
619 info.process_type_length = 7; | 607 info.process_type_length = 7; |
620 info.crash_url = NULL; | 608 info.crash_url = NULL; |
621 info.crash_url_length = 0; | 609 info.crash_url_length = 0; |
622 info.guid = google_update::posix_guid.data(); | 610 info.guid = child_process_logging::g_client_id; |
623 info.guid_length = google_update::posix_guid.length(); | 611 info.guid_length = my_strlen(child_process_logging::g_client_id); |
624 info.distro = base::linux_distro.data(); | 612 info.distro = base::g_linux_distro; |
625 info.distro_length = base::linux_distro.length(); | 613 info.distro_length = my_strlen(base::g_linux_distro); |
626 info.upload = upload; | 614 info.upload = upload; |
627 HandleCrashDump(info); | 615 HandleCrashDump(info); |
628 | 616 |
629 return true; | 617 return true; |
630 } | 618 } |
631 | 619 |
632 // Wrapper script, do not add more code here. | 620 // Wrapper script, do not add more code here. |
633 static bool CrashDoneNoUpload(const char* dump_path, | 621 static bool CrashDoneNoUpload(const char* dump_path, |
634 const char* minidump_id, | 622 const char* minidump_id, |
635 void* context, | 623 void* context, |
(...skipping 16 matching lines...) Expand all Loading... |
652 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); | 640 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); |
653 new google_breakpad::ExceptionHandler(dumps_path.value().c_str(), NULL, | 641 new google_breakpad::ExceptionHandler(dumps_path.value().c_str(), NULL, |
654 CrashDoneNoUpload, NULL, | 642 CrashDoneNoUpload, NULL, |
655 true /* install handlers */); | 643 true /* install handlers */); |
656 } else { | 644 } else { |
657 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDoneUpload, NULL, | 645 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDoneUpload, NULL, |
658 true /* install handlers */); | 646 true /* install handlers */); |
659 } | 647 } |
660 } | 648 } |
661 | 649 |
662 // This is defined in chrome/common/child_process_logging_linux.cc, it's the | |
663 // static string containing the current active URL. We send this in the crash | |
664 // report. | |
665 namespace child_process_logging { | |
666 extern std::string active_url; | |
667 } | |
668 | |
669 // Currently Non-Browser = Renderer and Plugins | 650 // Currently Non-Browser = Renderer and Plugins |
670 static bool | 651 static bool |
671 NonBrowserCrashHandler(const void* crash_context, size_t crash_context_size, | 652 NonBrowserCrashHandler(const void* crash_context, size_t crash_context_size, |
672 void* context) { | 653 void* context) { |
673 const int fd = reinterpret_cast<intptr_t>(context); | 654 const int fd = reinterpret_cast<intptr_t>(context); |
674 int fds[2] = { -1, -1 }; | 655 int fds[2] = { -1, -1 }; |
675 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { | 656 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { |
676 static const char msg[] = "Failed to create socket for crash dumping.\n"; | 657 static const char msg[] = "Failed to create socket for crash dumping.\n"; |
677 sys_write(2, msg, sizeof(msg)-1); | 658 sys_write(2, msg, sizeof(msg)-1); |
678 return false; | 659 return false; |
679 } | 660 } |
680 char guid[kGuidSize + 1] = {0}; | 661 char guid[kGuidSize + 1] = {0}; |
681 char crash_url[kMaxActiveURLSize + 1] = {0}; | 662 char crash_url[kMaxActiveURLSize + 1] = {0}; |
682 char distro[kDistroSize + 1] = {0}; | 663 char distro[kDistroSize + 1] = {0}; |
683 const size_t guid_len = std::min(google_update::posix_guid.size(), | 664 const size_t guid_len = |
684 kGuidSize); | 665 std::min(my_strlen(child_process_logging::g_client_id), kGuidSize); |
685 const size_t crash_url_len = | 666 const size_t crash_url_len = |
686 std::min(child_process_logging::active_url.size(), kMaxActiveURLSize); | 667 std::min(my_strlen(child_process_logging::g_active_url), |
| 668 kMaxActiveURLSize); |
687 const size_t distro_len = | 669 const size_t distro_len = |
688 std::min(base::linux_distro.size(), kDistroSize); | 670 std::min(my_strlen(base::g_linux_distro), kDistroSize); |
689 memcpy(guid, google_update::posix_guid.data(), guid_len); | 671 memcpy(guid, child_process_logging::g_client_id, guid_len); |
690 memcpy(crash_url, child_process_logging::active_url.data(), crash_url_len); | 672 memcpy(crash_url, child_process_logging::g_active_url, crash_url_len); |
691 memcpy(distro, base::linux_distro.data(), distro_len); | 673 memcpy(distro, base::g_linux_distro, distro_len); |
692 | 674 |
693 char b; // Dummy variable for sys_read below. | 675 char b; // Dummy variable for sys_read below. |
694 const char* b_addr = &b; // Get the address of |b| so we can create the | 676 const char* b_addr = &b; // Get the address of |b| so we can create the |
695 // expected /proc/[pid]/syscall content in the | 677 // expected /proc/[pid]/syscall content in the |
696 // browser to convert namespace tids. | 678 // browser to convert namespace tids. |
697 | 679 |
698 // The length of the control message: | 680 // The length of the control message: |
699 static const unsigned kControlMsgSize = CMSG_SPACE(2*sizeof(int)); | 681 static const unsigned kControlMsgSize = CMSG_SPACE(2*sizeof(int)); |
700 | 682 |
701 struct kernel_msghdr msg; | 683 struct kernel_msghdr msg; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 // dir. Instead, we set a command line flag for these processes. | 751 // dir. Instead, we set a command line flag for these processes. |
770 // Even though plugins are not chrooted, we share the same code path for | 752 // Even though plugins are not chrooted, we share the same code path for |
771 // simplicity. | 753 // simplicity. |
772 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) | 754 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) |
773 return; | 755 return; |
774 // Get the guid and linux distro from the command line switch. | 756 // Get the guid and linux distro from the command line switch. |
775 std::string switch_value = | 757 std::string switch_value = |
776 parsed_command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); | 758 parsed_command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); |
777 size_t separator = switch_value.find(","); | 759 size_t separator = switch_value.find(","); |
778 if (separator != std::string::npos) { | 760 if (separator != std::string::npos) { |
779 google_update::posix_guid = switch_value.substr(0, separator); | 761 child_process_logging::SetClientId(switch_value.substr(0, separator)); |
780 base::linux_distro = switch_value.substr(separator + 1); | 762 base::SetLinuxDistro(switch_value.substr(separator + 1)); |
781 } else { | 763 } else { |
782 google_update::posix_guid = switch_value; | 764 child_process_logging::SetClientId(switch_value); |
783 } | 765 } |
784 EnableNonBrowserCrashDumping(); | 766 EnableNonBrowserCrashDumping(); |
785 } | 767 } |
786 | 768 |
787 // Set the base process uptime value. | 769 // Set the base process uptime value. |
788 struct timeval tv; | 770 struct timeval tv; |
789 if (!gettimeofday(&tv, NULL)) | 771 if (!gettimeofday(&tv, NULL)) |
790 uptime = timeval_to_ms(&tv); | 772 uptime = timeval_to_ms(&tv); |
791 else | 773 else |
792 uptime = 0; | 774 uptime = 0; |
793 } | 775 } |
794 | 776 |
795 bool IsCrashReporterEnabled() { | 777 bool IsCrashReporterEnabled() { |
796 return is_crash_reporter_enabled; | 778 return is_crash_reporter_enabled; |
797 } | 779 } |
OLD | NEW |