OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // For linux_syscall_support.h. This makes it safe to call embedded system | 5 // For linux_syscall_support.h. This makes it safe to call embedded system |
6 // calls when in seccomp mode. | 6 // calls when in seccomp mode. |
7 | 7 |
8 #include "components/crash/app/breakpad_linux.h" | 8 #include "components/crash/app/breakpad_linux.h" |
9 | 9 |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "components/crash/app/breakpad_linux_impl.h" | 42 #include "components/crash/app/breakpad_linux_impl.h" |
43 #include "components/crash/app/crash_reporter_client.h" | 43 #include "components/crash/app/crash_reporter_client.h" |
44 #include "content/public/common/content_descriptors.h" | 44 #include "content/public/common/content_descriptors.h" |
45 | 45 |
46 #if defined(OS_ANDROID) | 46 #if defined(OS_ANDROID) |
47 #include <android/log.h> | 47 #include <android/log.h> |
48 #include <sys/stat.h> | 48 #include <sys/stat.h> |
49 | 49 |
50 #include "base/android/build_info.h" | 50 #include "base/android/build_info.h" |
51 #include "base/android/path_utils.h" | 51 #include "base/android/path_utils.h" |
| 52 #include "base/debug/leak_annotations.h" |
52 #endif | 53 #endif |
53 #include "third_party/lss/linux_syscall_support.h" | 54 #include "third_party/lss/linux_syscall_support.h" |
54 | 55 |
55 #if defined(ADDRESS_SANITIZER) | 56 #if defined(ADDRESS_SANITIZER) |
56 #include <ucontext.h> // for getcontext(). | 57 #include <ucontext.h> // for getcontext(). |
57 #endif | 58 #endif |
58 | 59 |
59 #if defined(OS_ANDROID) | 60 #if defined(OS_ANDROID) |
60 #define STAT_STRUCT struct stat | 61 #define STAT_STRUCT struct stat |
61 #define FSTAT_FUNC fstat | 62 #define FSTAT_FUNC fstat |
(...skipping 16 matching lines...) Expand all Loading... |
78 | 79 |
79 namespace { | 80 namespace { |
80 | 81 |
81 #if !defined(OS_CHROMEOS) | 82 #if !defined(OS_CHROMEOS) |
82 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 83 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
83 #endif | 84 #endif |
84 | 85 |
85 bool g_is_crash_reporter_enabled = false; | 86 bool g_is_crash_reporter_enabled = false; |
86 uint64_t g_process_start_time = 0; | 87 uint64_t g_process_start_time = 0; |
87 pid_t g_pid = 0; | 88 pid_t g_pid = 0; |
88 char* g_crash_log_path = NULL; | 89 char* g_crash_log_path = nullptr; |
89 ExceptionHandler* g_breakpad = NULL; | 90 ExceptionHandler* g_breakpad = nullptr; |
90 ExceptionHandler* g_microdump = NULL; | |
91 | 91 |
92 #if defined(ADDRESS_SANITIZER) | 92 #if defined(ADDRESS_SANITIZER) |
93 const char* g_asan_report_str = NULL; | 93 const char* g_asan_report_str = nullptr; |
94 #endif | 94 #endif |
95 #if defined(OS_ANDROID) | 95 #if defined(OS_ANDROID) |
96 char* g_process_type = NULL; | 96 char* g_process_type = nullptr; |
| 97 ExceptionHandler* g_microdump = nullptr; |
| 98 const char* g_microdump_build_fingerprint = nullptr; |
| 99 const char* g_microdump_product_info = nullptr; |
97 #endif | 100 #endif |
98 | 101 |
99 CrashKeyStorage* g_crash_keys = NULL; | 102 CrashKeyStorage* g_crash_keys = nullptr; |
100 | 103 |
101 // Writes the value |v| as 16 hex characters to the memory pointed at by | 104 // Writes the value |v| as 16 hex characters to the memory pointed at by |
102 // |output|. | 105 // |output|. |
103 void write_uint64_hex(char* output, uint64_t v) { | 106 void write_uint64_hex(char* output, uint64_t v) { |
104 static const char hextable[] = "0123456789abcdef"; | 107 static const char hextable[] = "0123456789abcdef"; |
105 | 108 |
106 for (int i = 15; i >= 0; --i) { | 109 for (int i = 15; i >= 0; --i) { |
107 output[i] = hextable[v & 15]; | 110 output[i] = hextable[v & 15]; |
108 v >>= 4; | 111 v >>= 4; |
109 } | 112 } |
(...skipping 16 matching lines...) Expand all Loading... |
126 ret += tv->tv_usec / 1000; | 129 ret += tv->tv_usec / 1000; |
127 return ret; | 130 return ret; |
128 } | 131 } |
129 | 132 |
130 // String buffer size to use to convert a uint64_t to string. | 133 // String buffer size to use to convert a uint64_t to string. |
131 const size_t kUint64StringSize = 21; | 134 const size_t kUint64StringSize = 21; |
132 | 135 |
133 void SetProcessStartTime() { | 136 void SetProcessStartTime() { |
134 // Set the base process start time value. | 137 // Set the base process start time value. |
135 struct timeval tv; | 138 struct timeval tv; |
136 if (!gettimeofday(&tv, NULL)) | 139 if (!gettimeofday(&tv, nullptr)) |
137 g_process_start_time = timeval_to_ms(&tv); | 140 g_process_start_time = timeval_to_ms(&tv); |
138 else | 141 else |
139 g_process_start_time = 0; | 142 g_process_start_time = 0; |
140 } | 143 } |
141 | 144 |
142 // uint64_t version of my_int_len() from | 145 // uint64_t version of my_int_len() from |
143 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the | 146 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the |
144 // given, non-negative integer when expressed in base 10. | 147 // given, non-negative integer when expressed in base 10. |
145 unsigned my_uint64_len(uint64_t i) { | 148 unsigned my_uint64_len(uint64_t i) { |
146 if (!i) | 149 if (!i) |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 AddString(g_sep); | 508 AddString(g_sep); |
506 AddItem(file_data, file_size); | 509 AddItem(file_data, file_size); |
507 Flush(); | 510 Flush(); |
508 } | 511 } |
509 #endif // defined(OS_CHROMEOS) | 512 #endif // defined(OS_CHROMEOS) |
510 | 513 |
511 void DumpProcess() { | 514 void DumpProcess() { |
512 if (g_breakpad) | 515 if (g_breakpad) |
513 g_breakpad->WriteMinidump(); | 516 g_breakpad->WriteMinidump(); |
514 | 517 |
| 518 #if defined(OS_ANDROID) |
515 // If microdumps are enabled write also a microdump on the system log. | 519 // If microdumps are enabled write also a microdump on the system log. |
516 if (g_microdump) | 520 if (g_microdump) |
517 g_microdump->WriteMinidump(); | 521 g_microdump->WriteMinidump(); |
| 522 #endif |
518 } | 523 } |
519 | 524 |
520 #if defined(OS_ANDROID) | 525 #if defined(OS_ANDROID) |
521 const char kGoogleBreakpad[] = "google-breakpad"; | 526 const char kGoogleBreakpad[] = "google-breakpad"; |
522 #endif | 527 #endif |
523 | 528 |
524 size_t WriteLog(const char* buf, size_t nbytes) { | 529 size_t WriteLog(const char* buf, size_t nbytes) { |
525 #if defined(OS_ANDROID) | 530 #if defined(OS_ANDROID) |
526 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); | 531 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); |
527 #else | 532 #else |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 minidump_descriptor.set_size_limit(-1); // unlimited. | 676 minidump_descriptor.set_size_limit(-1); // unlimited. |
672 } else { | 677 } else { |
673 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); | 678 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); |
674 } | 679 } |
675 #if defined(OS_ANDROID) | 680 #if defined(OS_ANDROID) |
676 unattended = true; // Android never uploads directly. | 681 unattended = true; // Android never uploads directly. |
677 #endif | 682 #endif |
678 if (unattended) { | 683 if (unattended) { |
679 g_breakpad = new ExceptionHandler( | 684 g_breakpad = new ExceptionHandler( |
680 minidump_descriptor, | 685 minidump_descriptor, |
681 NULL, | 686 nullptr, |
682 CrashDoneNoUpload, | 687 CrashDoneNoUpload, |
683 NULL, | 688 nullptr, |
684 true, // Install handlers. | 689 true, // Install handlers. |
685 -1); // Server file descriptor. -1 for in-process. | 690 -1); // Server file descriptor. -1 for in-process. |
686 return; | 691 return; |
687 } | 692 } |
688 | 693 |
689 #if !defined(OS_ANDROID) | 694 #if !defined(OS_ANDROID) |
690 // Attended mode | 695 // Attended mode |
691 g_breakpad = new ExceptionHandler( | 696 g_breakpad = new ExceptionHandler( |
692 minidump_descriptor, | 697 minidump_descriptor, |
693 NULL, | 698 nullptr, |
694 CrashDoneUpload, | 699 CrashDoneUpload, |
695 NULL, | 700 nullptr, |
696 true, // Install handlers. | 701 true, // Install handlers. |
697 -1); // Server file descriptor. -1 for in-process. | 702 -1); // Server file descriptor. -1 for in-process. |
698 #endif | 703 #endif |
699 } | 704 } |
700 | 705 |
701 #if defined(OS_ANDROID) | 706 #if defined(OS_ANDROID) |
702 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump, | 707 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump, |
703 void* context, | 708 void* context, |
704 bool succeeded) { | 709 bool succeeded) { |
705 // WARNING: this code runs in a compromised context. It may not call into | 710 // WARNING: this code runs in a compromised context. It may not call into |
706 // libc nor allocate memory normally. | 711 // libc nor allocate memory normally. |
707 if (!succeeded) { | 712 if (!succeeded) { |
708 static const char msg[] = "Microdump crash handler failed.\n"; | 713 static const char msg[] = "Microdump crash handler failed.\n"; |
709 WriteLog(msg, sizeof(msg) - 1); | 714 WriteLog(msg, sizeof(msg) - 1); |
710 return false; | 715 return false; |
711 } | 716 } |
712 | 717 |
713 const bool is_browser_process = (context != NULL); | 718 const bool is_browser_process = (context != nullptr); |
714 return FinalizeCrashDoneAndroid(is_browser_process); | 719 return FinalizeCrashDoneAndroid(is_browser_process); |
715 } | 720 } |
716 | 721 |
717 // The microdump handler does NOT upload anything. It just dumps out on the | 722 // The microdump handler does NOT upload anything. It just dumps out on the |
718 // system console (logcat) a restricted and serialized variant of a minidump. | 723 // system console (logcat) a restricted and serialized variant of a minidump. |
719 // See crbug.com/410294 for more details. | 724 // See crbug.com/410294 for more details. |
720 void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { | 725 void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { |
721 #if (!defined(ARCH_CPU_ARMEL) && !defined(ARCH_CPU_ARM64)) | 726 #if (!defined(ARCH_CPU_ARMEL) && !defined(ARCH_CPU_ARM64)) |
722 // TODO(primiano): For the moment microdumps are enabled only on arm (32/64). | 727 // TODO(primiano): For the moment microdumps are enabled only on arm (32/64). |
723 // Extend support to other architectures (requires some breakpad changes). | 728 // Extend support to other architectures (requires some breakpad changes). |
724 return; | 729 return; |
725 #endif | 730 #endif |
726 | 731 |
727 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) | 732 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) |
728 return; | 733 return; |
729 | 734 |
730 VLOG(1) << "Enabling microdumps crash handler (process_type:" | 735 VLOG(1) << "Enabling microdumps crash handler (process_type:" |
731 << process_type << ")"; | 736 << process_type << ")"; |
| 737 |
| 738 // The exception handler runs in a compromised context and cannot use c_str() |
| 739 // as that would require the heap. Therefore, we have to guarantee that the |
| 740 // build fingerprint and product info pointers are always valid. |
| 741 const char* product_name = nullptr; |
| 742 const char* product_version = nullptr; |
| 743 GetCrashReporterClient()->GetProductNameAndVersion(&product_name, |
| 744 &product_version); |
| 745 |
| 746 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); |
| 747 |
| 748 if (product_name && product_version) { |
| 749 g_microdump_product_info = strdup( |
| 750 (product_name + std::string(":") + product_version).c_str()); |
| 751 ANNOTATE_LEAKING_OBJECT_PTR(g_microdump_product_info); |
| 752 descriptor.SetMicrodumpProductInfo(g_microdump_product_info); |
| 753 } |
| 754 |
| 755 const char* android_build_fp = |
| 756 base::android::BuildInfo::GetInstance()->android_build_fp(); |
| 757 if (android_build_fp) { |
| 758 g_microdump_build_fingerprint = strdup(android_build_fp); |
| 759 ANNOTATE_LEAKING_OBJECT_PTR(g_microdump_build_fingerprint); |
| 760 descriptor.SetMicrodumpBuildFingerprint(g_microdump_build_fingerprint); |
| 761 } |
| 762 |
732 DCHECK(!g_microdump); | 763 DCHECK(!g_microdump); |
733 bool is_browser_process = process_type.empty() || process_type == "webview"; | 764 bool is_browser_process = process_type.empty() || process_type == "webview"; |
734 g_microdump = new ExceptionHandler( | 765 g_microdump = new ExceptionHandler( |
735 MinidumpDescriptor(MinidumpDescriptor::kMicrodumpOnConsole), | 766 descriptor, |
736 NULL, | 767 nullptr, |
737 MicrodumpCrashDone, | 768 MicrodumpCrashDone, |
738 reinterpret_cast<void*>(is_browser_process), | 769 reinterpret_cast<void*>(is_browser_process), |
739 true, // Install handlers. | 770 true, // Install handlers. |
740 -1); // Server file descriptor. -1 for in-process. | 771 -1); // Server file descriptor. -1 for in-process. |
741 return; | 772 return; |
742 } | 773 } |
743 | 774 |
744 bool CrashDoneInProcessNoUpload( | 775 bool CrashDoneInProcessNoUpload( |
745 const google_breakpad::MinidumpDescriptor& descriptor, | 776 const google_breakpad::MinidumpDescriptor& descriptor, |
746 void* context, | 777 void* context, |
747 const bool succeeded) { | 778 const bool succeeded) { |
748 // WARNING: this code runs in a compromised context. It may not call into | 779 // WARNING: this code runs in a compromised context. It may not call into |
749 // libc nor allocate memory normally. | 780 // libc nor allocate memory normally. |
750 if (!succeeded) { | 781 if (!succeeded) { |
751 static const char msg[] = "Crash dump generation failed.\n"; | 782 static const char msg[] = "Crash dump generation failed.\n"; |
752 WriteLog(msg, sizeof(msg) - 1); | 783 WriteLog(msg, sizeof(msg) - 1); |
753 return false; | 784 return false; |
754 } | 785 } |
755 | 786 |
756 // Start constructing the message to send to the browser. | 787 // Start constructing the message to send to the browser. |
757 BreakpadInfo info = {0}; | 788 BreakpadInfo info = {0}; |
758 info.filename = NULL; | 789 info.filename = nullptr; |
759 info.fd = descriptor.fd(); | 790 info.fd = descriptor.fd(); |
760 info.process_type = g_process_type; | 791 info.process_type = g_process_type; |
761 info.process_type_length = my_strlen(g_process_type); | 792 info.process_type_length = my_strlen(g_process_type); |
762 info.distro = NULL; | 793 info.distro = nullptr; |
763 info.distro_length = 0; | 794 info.distro_length = 0; |
764 info.upload = false; | 795 info.upload = false; |
765 info.process_start_time = g_process_start_time; | 796 info.process_start_time = g_process_start_time; |
766 info.pid = g_pid; | 797 info.pid = g_pid; |
767 info.crash_keys = g_crash_keys; | 798 info.crash_keys = g_crash_keys; |
768 HandleCrashDump(info); | 799 HandleCrashDump(info); |
769 return FinalizeCrashDoneAndroid(false /* is_browser_process */); | 800 return FinalizeCrashDoneAndroid(false /* is_browser_process */); |
770 } | 801 } |
771 | 802 |
772 void EnableNonBrowserCrashDumping(const std::string& process_type, | 803 void EnableNonBrowserCrashDumping(const std::string& process_type, |
(...skipping 18 matching lines...) Expand all Loading... |
791 } | 822 } |
792 SetProcessStartTime(); | 823 SetProcessStartTime(); |
793 g_pid = getpid(); | 824 g_pid = getpid(); |
794 | 825 |
795 g_is_crash_reporter_enabled = true; | 826 g_is_crash_reporter_enabled = true; |
796 // Save the process type (it is leaked). | 827 // Save the process type (it is leaked). |
797 const size_t process_type_len = process_type.size() + 1; | 828 const size_t process_type_len = process_type.size() + 1; |
798 g_process_type = new char[process_type_len]; | 829 g_process_type = new char[process_type_len]; |
799 strncpy(g_process_type, process_type.c_str(), process_type_len); | 830 strncpy(g_process_type, process_type.c_str(), process_type_len); |
800 new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), | 831 new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), |
801 NULL, CrashDoneInProcessNoUpload, NULL, true, -1); | 832 nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1); |
802 } | 833 } |
803 #else | 834 #else |
804 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer | 835 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer |
805 class NonBrowserCrashHandler : public google_breakpad::CrashGenerationClient { | 836 class NonBrowserCrashHandler : public google_breakpad::CrashGenerationClient { |
806 public: | 837 public: |
807 NonBrowserCrashHandler() | 838 NonBrowserCrashHandler() |
808 : server_fd_(base::GlobalDescriptors::GetInstance()->Get( | 839 : server_fd_(base::GlobalDescriptors::GetInstance()->Get( |
809 kCrashDumpSignal)) { | 840 kCrashDumpSignal)) { |
810 } | 841 } |
811 | 842 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 DISALLOW_COPY_AND_ASSIGN(NonBrowserCrashHandler); | 926 DISALLOW_COPY_AND_ASSIGN(NonBrowserCrashHandler); |
896 }; | 927 }; |
897 | 928 |
898 void EnableNonBrowserCrashDumping() { | 929 void EnableNonBrowserCrashDumping() { |
899 g_is_crash_reporter_enabled = true; | 930 g_is_crash_reporter_enabled = true; |
900 // We deliberately leak this object. | 931 // We deliberately leak this object. |
901 DCHECK(!g_breakpad); | 932 DCHECK(!g_breakpad); |
902 | 933 |
903 g_breakpad = new ExceptionHandler( | 934 g_breakpad = new ExceptionHandler( |
904 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. | 935 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. |
905 NULL, | 936 nullptr, |
906 NULL, | 937 nullptr, |
907 NULL, | 938 nullptr, |
908 true, | 939 true, |
909 -1); | 940 -1); |
910 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); | 941 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); |
911 } | 942 } |
912 #endif // defined(OS_ANDROID) | 943 #endif // defined(OS_ANDROID) |
913 | 944 |
914 void SetCrashKeyValue(const base::StringPiece& key, | 945 void SetCrashKeyValue(const base::StringPiece& key, |
915 const base::StringPiece& value) { | 946 const base::StringPiece& value) { |
916 g_crash_keys->SetKeyValue(key.data(), value.data()); | 947 g_crash_keys->SetKeyValue(key.data(), value.data()); |
917 } | 948 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 exe_flag[0] = '\0'; | 1081 exe_flag[0] = '\0'; |
1051 my_strlcat(exe_flag, kExeBuf, buf_len); | 1082 my_strlcat(exe_flag, kExeBuf, buf_len); |
1052 my_strlcat(exe_flag, exe_buf, buf_len); | 1083 my_strlcat(exe_flag, exe_buf, buf_len); |
1053 | 1084 |
1054 const char* args[] = { | 1085 const char* args[] = { |
1055 kCrashReporterBinary, | 1086 kCrashReporterBinary, |
1056 chrome_flag, | 1087 chrome_flag, |
1057 pid_flag, | 1088 pid_flag, |
1058 uid_flag, | 1089 uid_flag, |
1059 exe_flag, | 1090 exe_flag, |
1060 NULL, | 1091 nullptr, |
1061 }; | 1092 }; |
1062 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1093 static const char msg[] = "Cannot upload crash dump: cannot exec " |
1063 "/sbin/crash_reporter\n"; | 1094 "/sbin/crash_reporter\n"; |
1064 #else | 1095 #else |
1065 // The --header argument to wget looks like: | 1096 // The --header argument to wget looks like: |
1066 // --header=Content-Type: multipart/form-data; boundary=XYZ | 1097 // --header=Content-Type: multipart/form-data; boundary=XYZ |
1067 // where the boundary has two fewer leading '-' chars | 1098 // where the boundary has two fewer leading '-' chars |
1068 static const char header_msg[] = | 1099 static const char header_msg[] = |
1069 "--header=Content-Type: multipart/form-data; boundary="; | 1100 "--header=Content-Type: multipart/form-data; boundary="; |
1070 char* const header = reinterpret_cast<char*>(allocator->Alloc( | 1101 char* const header = reinterpret_cast<char*>(allocator->Alloc( |
(...skipping 14 matching lines...) Expand all Loading... |
1085 static const char kWgetBinary[] = "/usr/bin/wget"; | 1116 static const char kWgetBinary[] = "/usr/bin/wget"; |
1086 const char* args[] = { | 1117 const char* args[] = { |
1087 kWgetBinary, | 1118 kWgetBinary, |
1088 header, | 1119 header, |
1089 post_file, | 1120 post_file, |
1090 kUploadURL, | 1121 kUploadURL, |
1091 "--timeout=10", // Set a timeout so we don't hang forever. | 1122 "--timeout=10", // Set a timeout so we don't hang forever. |
1092 "--tries=1", // Don't retry if the upload fails. | 1123 "--tries=1", // Don't retry if the upload fails. |
1093 "-O", // output reply to fd 3 | 1124 "-O", // output reply to fd 3 |
1094 "/dev/fd/3", | 1125 "/dev/fd/3", |
1095 NULL, | 1126 nullptr, |
1096 }; | 1127 }; |
1097 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1128 static const char msg[] = "Cannot upload crash dump: cannot exec " |
1098 "/usr/bin/wget\n"; | 1129 "/usr/bin/wget\n"; |
1099 #endif | 1130 #endif |
1100 execve(args[0], const_cast<char**>(args), environ); | 1131 execve(args[0], const_cast<char**>(args), environ); |
1101 WriteLog(msg, sizeof(msg) - 1); | 1132 WriteLog(msg, sizeof(msg) - 1); |
1102 sys__exit(1); | 1133 sys__exit(1); |
1103 } | 1134 } |
1104 | 1135 |
1105 // Runs in the helper process to wait for the upload process running | 1136 // Runs in the helper process to wait for the upload process running |
(...skipping 24 matching lines...) Expand all Loading... |
1130 if (bytes_read == bytes_to_read) | 1161 if (bytes_read == bytes_to_read) |
1131 break; | 1162 break; |
1132 } | 1163 } |
1133 // |ret| == 0 -> timed out, continue waiting. | 1164 // |ret| == 0 -> timed out, continue waiting. |
1134 // or |bytes_read| < |bytes_to_read| still, keep reading. | 1165 // or |bytes_read| < |bytes_to_read| still, keep reading. |
1135 } | 1166 } |
1136 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. | 1167 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. |
1137 return bytes_read; | 1168 return bytes_read; |
1138 } | 1169 } |
1139 | 1170 |
1140 // |buf| should be |expected_len| + 1 characters in size and NULL terminated. | 1171 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
1141 bool IsValidCrashReportId(const char* buf, size_t bytes_read, | 1172 bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
1142 size_t expected_len) { | 1173 size_t expected_len) { |
1143 if (bytes_read != expected_len) | 1174 if (bytes_read != expected_len) |
1144 return false; | 1175 return false; |
1145 #if defined(OS_CHROMEOS) | 1176 #if defined(OS_CHROMEOS) |
1146 return my_strcmp(buf, "_sys_cr_finished") == 0; | 1177 return my_strcmp(buf, "_sys_cr_finished") == 0; |
1147 #else | 1178 #else |
1148 for (size_t i = 0; i < bytes_read; ++i) { | 1179 for (size_t i = 0; i < bytes_read; ++i) { |
1149 if (!my_isxdigit(buf[i])) | 1180 if (!my_isxdigit(buf[i])) |
1150 return false; | 1181 return false; |
1151 } | 1182 } |
1152 return true; | 1183 return true; |
1153 #endif | 1184 #endif |
1154 } | 1185 } |
1155 | 1186 |
1156 // |buf| should be |expected_len| + 1 characters in size and NULL terminated. | 1187 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
1157 void HandleCrashReportId(const char* buf, size_t bytes_read, | 1188 void HandleCrashReportId(const char* buf, size_t bytes_read, |
1158 size_t expected_len) { | 1189 size_t expected_len) { |
1159 WriteNewline(); | 1190 WriteNewline(); |
1160 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { | 1191 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { |
1161 #if defined(OS_CHROMEOS) | 1192 #if defined(OS_CHROMEOS) |
1162 static const char msg[] = | 1193 static const char msg[] = |
1163 "System crash-reporter failed to process crash report."; | 1194 "System crash-reporter failed to process crash report."; |
1164 #else | 1195 #else |
1165 static const char msg[] = "Failed to get crash dump id."; | 1196 static const char msg[] = "Failed to get crash dump id."; |
1166 #endif | 1197 #endif |
(...skipping 12 matching lines...) Expand all Loading... |
1179 WriteLog(msg, sizeof(msg) - 1); | 1210 WriteLog(msg, sizeof(msg) - 1); |
1180 #else | 1211 #else |
1181 // Write crash dump id to stderr. | 1212 // Write crash dump id to stderr. |
1182 static const char msg[] = "Crash dump id: "; | 1213 static const char msg[] = "Crash dump id: "; |
1183 WriteLog(msg, sizeof(msg) - 1); | 1214 WriteLog(msg, sizeof(msg) - 1); |
1184 WriteLog(buf, my_strlen(buf)); | 1215 WriteLog(buf, my_strlen(buf)); |
1185 WriteNewline(); | 1216 WriteNewline(); |
1186 | 1217 |
1187 // Write crash dump id to crash log as: seconds_since_epoch,crash_id | 1218 // Write crash dump id to crash log as: seconds_since_epoch,crash_id |
1188 struct kernel_timeval tv; | 1219 struct kernel_timeval tv; |
1189 if (g_crash_log_path && !sys_gettimeofday(&tv, NULL)) { | 1220 if (g_crash_log_path && !sys_gettimeofday(&tv, nullptr)) { |
1190 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; | 1221 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; |
1191 char time_str[kUint64StringSize]; | 1222 char time_str[kUint64StringSize]; |
1192 const unsigned time_len = my_uint64_len(time); | 1223 const unsigned time_len = my_uint64_len(time); |
1193 my_uint64tos(time_str, time, time_len); | 1224 my_uint64tos(time_str, time, time_len); |
1194 | 1225 |
1195 const int kLogOpenFlags = O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC; | 1226 const int kLogOpenFlags = O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC; |
1196 int log_fd = sys_open(g_crash_log_path, kLogOpenFlags, 0600); | 1227 int log_fd = sys_open(g_crash_log_path, kLogOpenFlags, 0600); |
1197 if (log_fd > 0) { | 1228 if (log_fd > 0) { |
1198 sys_write(log_fd, time_str, time_len); | 1229 sys_write(log_fd, time_str, time_len); |
1199 sys_write(log_fd, ",", 1); | 1230 sys_write(log_fd, ",", 1); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 return "chrome-crash-unknown-process"; | 1265 return "chrome-crash-unknown-process"; |
1235 } | 1266 } |
1236 #endif | 1267 #endif |
1237 | 1268 |
1238 void HandleCrashDump(const BreakpadInfo& info) { | 1269 void HandleCrashDump(const BreakpadInfo& info) { |
1239 int dumpfd; | 1270 int dumpfd; |
1240 bool keep_fd = false; | 1271 bool keep_fd = false; |
1241 size_t dump_size; | 1272 size_t dump_size; |
1242 uint8_t* dump_data; | 1273 uint8_t* dump_data; |
1243 google_breakpad::PageAllocator allocator; | 1274 google_breakpad::PageAllocator allocator; |
1244 const char* exe_buf = NULL; | 1275 const char* exe_buf = nullptr; |
1245 | 1276 |
1246 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { | 1277 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { |
1247 return; | 1278 return; |
1248 } | 1279 } |
1249 | 1280 |
1250 #if defined(OS_CHROMEOS) | 1281 #if defined(OS_CHROMEOS) |
1251 // Grab the crashing process' name now, when it should still be available. | 1282 // Grab the crashing process' name now, when it should still be available. |
1252 // If we try to do this later in our grandchild the crashing process has | 1283 // If we try to do this later in our grandchild the crashing process has |
1253 // already terminated. | 1284 // already terminated. |
1254 exe_buf = GetCrashingProcessName(info, &allocator); | 1285 exe_buf = GetCrashingProcessName(info, &allocator); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1429 writer.AddBoundary(); | 1460 writer.AddBoundary(); |
1430 writer.AddPairString( | 1461 writer.AddPairString( |
1431 android_build_fp, android_build_info->android_build_fp()); | 1462 android_build_fp, android_build_info->android_build_fp()); |
1432 writer.AddBoundary(); | 1463 writer.AddBoundary(); |
1433 writer.AddPairString(device, android_build_info->device()); | 1464 writer.AddPairString(device, android_build_info->device()); |
1434 writer.AddBoundary(); | 1465 writer.AddBoundary(); |
1435 writer.AddPairString(model, android_build_info->model()); | 1466 writer.AddPairString(model, android_build_info->model()); |
1436 writer.AddBoundary(); | 1467 writer.AddBoundary(); |
1437 writer.AddPairString(brand, android_build_info->brand()); | 1468 writer.AddPairString(brand, android_build_info->brand()); |
1438 writer.AddBoundary(); | 1469 writer.AddBoundary(); |
1439 if (android_build_info->java_exception_info() != NULL) { | 1470 if (android_build_info->java_exception_info() != nullptr) { |
1440 writer.AddPairString(exception_info, | 1471 writer.AddPairString(exception_info, |
1441 android_build_info->java_exception_info()); | 1472 android_build_info->java_exception_info()); |
1442 writer.AddBoundary(); | 1473 writer.AddBoundary(); |
1443 } | 1474 } |
1444 #endif | 1475 #endif |
1445 writer.Flush(); | 1476 writer.Flush(); |
1446 } | 1477 } |
1447 | 1478 |
1448 if (info.process_start_time > 0) { | 1479 if (info.process_start_time > 0) { |
1449 struct kernel_timeval tv; | 1480 struct kernel_timeval tv; |
1450 if (!sys_gettimeofday(&tv, NULL)) { | 1481 if (!sys_gettimeofday(&tv, nullptr)) { |
1451 uint64_t time = kernel_timeval_to_ms(&tv); | 1482 uint64_t time = kernel_timeval_to_ms(&tv); |
1452 if (time > info.process_start_time) { | 1483 if (time > info.process_start_time) { |
1453 time -= info.process_start_time; | 1484 time -= info.process_start_time; |
1454 char time_str[kUint64StringSize]; | 1485 char time_str[kUint64StringSize]; |
1455 const unsigned time_len = my_uint64_len(time); | 1486 const unsigned time_len = my_uint64_len(time); |
1456 my_uint64tos(time_str, time, time_len); | 1487 my_uint64tos(time_str, time, time_len); |
1457 | 1488 |
1458 static const char process_time_msg[] = "ptime"; | 1489 static const char process_time_msg[] = "ptime"; |
1459 writer.AddPairData(process_time_msg, sizeof(process_time_msg) - 1, | 1490 writer.AddPairData(process_time_msg, sizeof(process_time_msg) - 1, |
1460 time_str, time_len); | 1491 time_str, time_len); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 // Helper process. | 1630 // Helper process. |
1600 if (upload_child > 0) { | 1631 if (upload_child > 0) { |
1601 IGNORE_RET(sys_close(fds[1])); | 1632 IGNORE_RET(sys_close(fds[1])); |
1602 | 1633 |
1603 const size_t kCrashIdLength = 16; | 1634 const size_t kCrashIdLength = 16; |
1604 char id_buf[kCrashIdLength + 1]; | 1635 char id_buf[kCrashIdLength + 1]; |
1605 size_t bytes_read = | 1636 size_t bytes_read = |
1606 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); | 1637 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); |
1607 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); | 1638 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); |
1608 | 1639 |
1609 if (sys_waitpid(upload_child, NULL, WNOHANG) == 0) { | 1640 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { |
1610 // Upload process is still around, kill it. | 1641 // Upload process is still around, kill it. |
1611 sys_kill(upload_child, SIGKILL); | 1642 sys_kill(upload_child, SIGKILL); |
1612 } | 1643 } |
1613 } | 1644 } |
1614 } | 1645 } |
1615 | 1646 |
1616 // Helper process. | 1647 // Helper process. |
1617 IGNORE_RET(sys_unlink(info.filename)); | 1648 IGNORE_RET(sys_unlink(info.filename)); |
1618 #if defined(ADDRESS_SANITIZER) | 1649 #if defined(ADDRESS_SANITIZER) |
1619 IGNORE_RET(sys_unlink(info.log_filename)); | 1650 IGNORE_RET(sys_unlink(info.log_filename)); |
1620 #endif | 1651 #endif |
1621 IGNORE_RET(sys_unlink(temp_file)); | 1652 IGNORE_RET(sys_unlink(temp_file)); |
1622 sys__exit(0); | 1653 sys__exit(0); |
1623 } | 1654 } |
1624 | 1655 |
1625 // Main browser process. | 1656 // Main browser process. |
1626 if (child <= 0) | 1657 if (child <= 0) |
1627 return; | 1658 return; |
1628 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); | 1659 (void) HANDLE_EINTR(sys_waitpid(child, nullptr, 0)); |
1629 } | 1660 } |
1630 | 1661 |
1631 void InitCrashReporter(const std::string& process_type) { | 1662 void InitCrashReporter(const std::string& process_type) { |
1632 #if defined(OS_ANDROID) | 1663 #if defined(OS_ANDROID) |
1633 // This will guarantee that the BuildInfo has been initialized and subsequent | 1664 // This will guarantee that the BuildInfo has been initialized and subsequent |
1634 // calls will not require memory allocation. | 1665 // calls will not require memory allocation. |
1635 base::android::BuildInfo::GetInstance(); | 1666 base::android::BuildInfo::GetInstance(); |
1636 | 1667 |
1637 // Handler registration is LIFO. Install the microdump handler first, such | 1668 // Handler registration is LIFO. Install the microdump handler first, such |
1638 // that if conventional minidump crash reporting is enabled below, it takes | 1669 // that if conventional minidump crash reporting is enabled below, it takes |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 } | 1739 } |
1709 } | 1740 } |
1710 } | 1741 } |
1711 #endif // OS_ANDROID | 1742 #endif // OS_ANDROID |
1712 | 1743 |
1713 bool IsCrashReporterEnabled() { | 1744 bool IsCrashReporterEnabled() { |
1714 return g_is_crash_reporter_enabled; | 1745 return g_is_crash_reporter_enabled; |
1715 } | 1746 } |
1716 | 1747 |
1717 } // namespace breakpad | 1748 } // namespace breakpad |
OLD | NEW |