OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint" | 7 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint" |
8 | 8 |
9 #include "chrome/app/breakpad_linux.h" | 9 #include "chrome/app/breakpad_linux.h" |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 "third_party/lss/linux_syscall_support.h" | 52 #include "third_party/lss/linux_syscall_support.h" |
53 #else | 53 #else |
54 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" | 54 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" |
55 #endif | 55 #endif |
56 | 56 |
57 #if defined(ADDRESS_SANITIZER) | |
58 #include <ucontext.h> // for getcontext(). | |
59 #endif | |
60 | |
61 #if defined(OS_ANDROID) | 57 #if defined(OS_ANDROID) |
62 #define STAT_STRUCT struct stat | 58 #define STAT_STRUCT struct stat |
63 #define FSTAT_FUNC fstat | 59 #define FSTAT_FUNC fstat |
64 #else | 60 #else |
65 #define STAT_STRUCT struct kernel_stat | 61 #define STAT_STRUCT struct kernel_stat |
66 #define FSTAT_FUNC sys_fstat | 62 #define FSTAT_FUNC sys_fstat |
67 #endif | 63 #endif |
68 | 64 |
69 // Some versions of gcc are prone to warn about unused return values. In cases | 65 // Some versions of gcc are prone to warn about unused return values. In cases |
70 // where we either a) know the call cannot fail, or b) there is nothing we | 66 // where we either a) know the call cannot fail, or b) there is nothing we |
71 // can do when a call fails, we mark the return code as ignored. This avoids | 67 // can do when a call fails, we mark the return code as ignored. This avoids |
72 // spurious compiler warnings. | 68 // spurious compiler warnings. |
73 #define IGNORE_RET(x) do { if (x); } while (0) | 69 #define IGNORE_RET(x) do { if (x); } while (0) |
74 | 70 |
75 #if !defined(ADDRESS_SANITIZER) | |
76 static const char kUploadURL[] = | 71 static const char kUploadURL[] = |
77 "https://clients2.google.com/cr/report"; | 72 "https://clients2.google.com/cr/report"; |
78 #else | |
79 // AddressSanitizer should currently upload the crash reports to the staging | |
80 // crash server. | |
81 static const char kUploadURL[] = | |
82 "https://clients2.google.com/cr/staging_report"; | |
83 #endif | |
84 | 73 |
85 static bool g_is_crash_reporter_enabled = false; | 74 static bool g_is_crash_reporter_enabled = false; |
86 static uint64_t g_process_start_time = 0; | 75 static uint64_t g_process_start_time = 0; |
87 static char* g_crash_log_path = NULL; | 76 static char* g_crash_log_path = NULL; |
88 static google_breakpad::ExceptionHandler* g_breakpad = NULL; | 77 static google_breakpad::ExceptionHandler* g_breakpad = NULL; |
89 #if defined(ADDRESS_SANITIZER) | |
90 static char* g_asan_report_str = NULL; | |
91 #endif | |
92 | 78 |
93 // Writes the value |v| as 16 hex characters to the memory pointed at by | 79 // Writes the value |v| as 16 hex characters to the memory pointed at by |
94 // |output|. | 80 // |output|. |
95 static void write_uint64_hex(char* output, uint64_t v) { | 81 static void write_uint64_hex(char* output, uint64_t v) { |
96 static const char hextable[] = "0123456789abcdef"; | 82 static const char hextable[] = "0123456789abcdef"; |
97 | 83 |
98 for (int i = 15; i >= 0; --i) { | 84 for (int i = 15; i >= 0; --i) { |
99 output[i] = hextable[v & 15]; | 85 output[i] = hextable[v & 15]; |
100 v >>= 4; | 86 v >>= 4; |
101 } | 87 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 #endif | 162 #endif |
177 | 163 |
178 namespace { | 164 namespace { |
179 | 165 |
180 // MIME substrings. | 166 // MIME substrings. |
181 const char g_rn[] = "\r\n"; | 167 const char g_rn[] = "\r\n"; |
182 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 168 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
183 const char g_quote_msg[] = "\""; | 169 const char g_quote_msg[] = "\""; |
184 const char g_dashdash_msg[] = "--"; | 170 const char g_dashdash_msg[] = "--"; |
185 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; | 171 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; |
186 #if defined(ADDRESS_SANITIZER) | |
187 const char g_log_msg[] = "upload_file_log\"; filename=\"log\""; | |
188 #endif | |
189 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; | 172 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; |
190 | 173 |
191 // MimeWriter manages an iovec for writing MIMEs to a file. | 174 // MimeWriter manages an iovec for writing MIMEs to a file. |
192 class MimeWriter { | 175 class MimeWriter { |
193 public: | 176 public: |
194 static const int kIovCapacity = 30; | 177 static const int kIovCapacity = 30; |
195 static const size_t kMaxCrashChunkSize = 64; | 178 static const size_t kMaxCrashChunkSize = 64; |
196 | 179 |
197 MimeWriter(int fd, const char* const mime_boundary); | 180 MimeWriter(int fd, const char* const mime_boundary); |
198 ~MimeWriter(); | 181 ~MimeWriter(); |
(...skipping 19 matching lines...) Expand all Loading... |
218 // Append key/value pair, splitting value into chunks no larger than | 201 // Append key/value pair, splitting value into chunks no larger than |
219 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. | 202 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. |
220 // The msg_type string will have a counter suffix to distinguish each chunk. | 203 // The msg_type string will have a counter suffix to distinguish each chunk. |
221 void AddPairDataInChunks(const char* msg_type, | 204 void AddPairDataInChunks(const char* msg_type, |
222 size_t msg_type_size, | 205 size_t msg_type_size, |
223 const char* msg_data, | 206 const char* msg_data, |
224 size_t msg_data_size, | 207 size_t msg_data_size, |
225 size_t chunk_size, | 208 size_t chunk_size, |
226 bool strip_trailing_spaces); | 209 bool strip_trailing_spaces); |
227 | 210 |
228 // Add binary file contents to be uploaded with the specified filename. | 211 // Add binary file dump. Currently this is only done once, so the name is |
229 void AddFileContents(const char* filename_msg, | 212 // fixed. |
230 uint8_t* file_data, | 213 void AddFileDump(uint8_t* file_data, |
231 size_t file_size); | 214 size_t file_size); |
232 | 215 |
233 // Flush any pending iovecs to the output file. | 216 // Flush any pending iovecs to the output file. |
234 void Flush() { | 217 void Flush() { |
235 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); | 218 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); |
236 iov_index_ = 0; | 219 iov_index_ = 0; |
237 } | 220 } |
238 | 221 |
239 private: | 222 private: |
240 void AddItem(const void* base, size_t size); | 223 void AddItem(const void* base, size_t size); |
241 // Minor performance trade-off for easier-to-maintain code. | 224 // Minor performance trade-off for easier-to-maintain code. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 } | 303 } |
321 AddString(g_rn); | 304 AddString(g_rn); |
322 AddBoundary(); | 305 AddBoundary(); |
323 Flush(); | 306 Flush(); |
324 | 307 |
325 done += chunk_len; | 308 done += chunk_len; |
326 msg_length -= chunk_len; | 309 msg_length -= chunk_len; |
327 } | 310 } |
328 } | 311 } |
329 | 312 |
330 void MimeWriter::AddFileContents(const char* filename_msg, uint8_t* file_data, | 313 void MimeWriter::AddFileDump(uint8_t* file_data, |
331 size_t file_size) { | 314 size_t file_size) { |
332 AddString(g_form_data_msg); | 315 AddString(g_form_data_msg); |
333 AddString(filename_msg); | 316 AddString(g_dump_msg); |
334 AddString(g_rn); | 317 AddString(g_rn); |
335 AddString(g_content_type_msg); | 318 AddString(g_content_type_msg); |
336 AddString(g_rn); | 319 AddString(g_rn); |
337 AddString(g_rn); | 320 AddString(g_rn); |
338 AddItem(file_data, file_size); | 321 AddItem(file_data, file_size); |
339 AddString(g_rn); | 322 AddString(g_rn); |
340 } | 323 } |
341 | 324 |
342 void MimeWriter::AddItem(const void* base, size_t size) { | 325 void MimeWriter::AddItem(const void* base, size_t size) { |
343 // Check if the iovec is full and needs to be flushed to output file. | 326 // Check if the iovec is full and needs to be flushed to output file. |
(...skipping 25 matching lines...) Expand all Loading... |
369 size_t WriteLog(const char* buf, size_t nbytes) { | 352 size_t WriteLog(const char* buf, size_t nbytes) { |
370 #if defined(OS_ANDROID) | 353 #if defined(OS_ANDROID) |
371 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); | 354 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); |
372 #else | 355 #else |
373 return sys_write(2, buf, nbytes); | 356 return sys_write(2, buf, nbytes); |
374 #endif | 357 #endif |
375 } | 358 } |
376 | 359 |
377 } // namespace | 360 } // namespace |
378 | 361 |
379 void LoadDataFromFile(google_breakpad::PageAllocator& allocator, | 362 void HandleCrashDump(const BreakpadInfo& info) { |
380 const BreakpadInfo& info, int* fd, | |
381 uint8_t** file_data, size_t* size, | |
382 const char* filename) { | |
383 // WARNING: this code runs in a compromised context. It may not call into | 363 // WARNING: this code runs in a compromised context. It may not call into |
384 // libc nor allocate memory normally. | 364 // libc nor allocate memory normally. |
385 *fd = sys_open(filename, O_RDONLY, 0); | |
386 *size = 0; | |
387 | 365 |
388 if (*fd < 0) { | 366 const int dumpfd = sys_open(info.filename, O_RDONLY, 0); |
| 367 if (dumpfd < 0) { |
389 static const char msg[] = "Cannot upload crash dump: failed to open\n"; | 368 static const char msg[] = "Cannot upload crash dump: failed to open\n"; |
390 WriteLog(msg, sizeof(msg)); | 369 WriteLog(msg, sizeof(msg)); |
391 return; | 370 return; |
392 } | 371 } |
393 STAT_STRUCT st; | 372 STAT_STRUCT st; |
394 if (FSTAT_FUNC(*fd, &st) != 0) { | 373 if (FSTAT_FUNC(dumpfd, &st) != 0) { |
395 static const char msg[] = "Cannot upload crash dump: stat failed\n"; | 374 static const char msg[] = "Cannot upload crash dump: stat failed\n"; |
396 WriteLog(msg, sizeof(msg)); | 375 WriteLog(msg, sizeof(msg)); |
397 IGNORE_RET(sys_close(*fd)); | 376 IGNORE_RET(sys_close(dumpfd)); |
398 return; | 377 return; |
399 } | 378 } |
400 | 379 |
401 *file_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); | 380 google_breakpad::PageAllocator allocator; |
402 if (!(*file_data)) { | 381 |
| 382 uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); |
| 383 if (!dump_data) { |
403 static const char msg[] = "Cannot upload crash dump: cannot alloc\n"; | 384 static const char msg[] = "Cannot upload crash dump: cannot alloc\n"; |
404 WriteLog(msg, sizeof(msg)); | 385 WriteLog(msg, sizeof(msg)); |
405 IGNORE_RET(sys_close(*fd)); | 386 IGNORE_RET(sys_close(dumpfd)); |
406 return; | 387 return; |
407 } | 388 } |
408 my_memset(*file_data, 0xf, st.st_size); | |
409 | 389 |
410 *size = st.st_size; | 390 sys_read(dumpfd, dump_data, st.st_size); |
411 sys_read(*fd, *file_data, *size); | 391 IGNORE_RET(sys_close(dumpfd)); |
412 IGNORE_RET(sys_close(*fd)); | |
413 } | |
414 | |
415 void HandleCrashDump(const BreakpadInfo& info) { | |
416 int dumpfd; | |
417 size_t dump_size; | |
418 uint8_t *dump_data; | |
419 google_breakpad::PageAllocator allocator; | |
420 LoadDataFromFile(allocator, info, &dumpfd, &dump_data, &dump_size, | |
421 info.filename); | |
422 #if defined(ADDRESS_SANITIZER) | |
423 int logfd; | |
424 size_t log_size; | |
425 uint8_t *log_data; | |
426 // Load the AddressSanitizer log into log_data. | |
427 LoadDataFromFile(allocator, info, &logfd, &log_data, &log_size, | |
428 info.log_filename); | |
429 #endif | |
430 | 392 |
431 // We need to build a MIME block for uploading to the server. Since we are | 393 // We need to build a MIME block for uploading to the server. Since we are |
432 // going to fork and run wget, it needs to be written to a temp file. | 394 // going to fork and run wget, it needs to be written to a temp file. |
| 395 |
433 const int ufd = sys_open("/dev/urandom", O_RDONLY, 0); | 396 const int ufd = sys_open("/dev/urandom", O_RDONLY, 0); |
434 if (ufd < 0) { | 397 if (ufd < 0) { |
435 static const char msg[] = "Cannot upload crash dump because /dev/urandom" | 398 static const char msg[] = "Cannot upload crash dump because /dev/urandom" |
436 " is missing\n"; | 399 " is missing\n"; |
437 WriteLog(msg, sizeof(msg) - 1); | 400 WriteLog(msg, sizeof(msg) - 1); |
438 return; | 401 return; |
439 } | 402 } |
440 | 403 |
441 static const char temp_file_template[] = | 404 static const char temp_file_template[] = |
442 "/tmp/chromium-upload-XXXXXXXXXXXXXXXX"; | 405 "/tmp/chromium-upload-XXXXXXXXXXXXXXXX"; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 char oom_size_str[kUint64StringSize]; | 717 char oom_size_str[kUint64StringSize]; |
755 const unsigned oom_size_len = my_uint64_len(info.oom_size); | 718 const unsigned oom_size_len = my_uint64_len(info.oom_size); |
756 my_uint64tos(oom_size_str, info.oom_size, oom_size_len); | 719 my_uint64tos(oom_size_str, info.oom_size, oom_size_len); |
757 static const char oom_size_msg[] = "oom-size"; | 720 static const char oom_size_msg[] = "oom-size"; |
758 writer.AddPairData(oom_size_msg, sizeof(oom_size_msg) - 1, | 721 writer.AddPairData(oom_size_msg, sizeof(oom_size_msg) - 1, |
759 oom_size_str, oom_size_len); | 722 oom_size_str, oom_size_len); |
760 writer.AddBoundary(); | 723 writer.AddBoundary(); |
761 writer.Flush(); | 724 writer.Flush(); |
762 } | 725 } |
763 | 726 |
764 writer.AddFileContents(g_dump_msg, dump_data, dump_size); | 727 writer.AddFileDump(dump_data, st.st_size); |
765 #if defined(ADDRESS_SANITIZER) | |
766 // Append a multipart boundary and the contents of the AddressSanitizer log. | |
767 writer.AddBoundary(); | |
768 writer.AddFileContents(g_log_msg, log_data, log_size); | |
769 #endif | |
770 writer.AddEnd(); | 728 writer.AddEnd(); |
771 writer.Flush(); | 729 writer.Flush(); |
772 | 730 |
773 IGNORE_RET(sys_close(temp_file_fd)); | 731 IGNORE_RET(sys_close(temp_file_fd)); |
774 | 732 |
775 #if defined(OS_ANDROID) | 733 #if defined(OS_ANDROID) |
776 __android_log_write(ANDROID_LOG_WARN, | 734 __android_log_write(ANDROID_LOG_WARN, |
777 kGoogleBreakpad, | 735 kGoogleBreakpad, |
778 "Output crash dump file:"); | 736 "Output crash dump file:"); |
779 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); | 737 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 } | 898 } |
941 if (sys_waitpid(wget_child, NULL, WNOHANG) == 0) { | 899 if (sys_waitpid(wget_child, NULL, WNOHANG) == 0) { |
942 // Wget process is still around, kill it. | 900 // Wget process is still around, kill it. |
943 sys_kill(wget_child, SIGKILL); | 901 sys_kill(wget_child, SIGKILL); |
944 } | 902 } |
945 } | 903 } |
946 } | 904 } |
947 | 905 |
948 // Helper process. | 906 // Helper process. |
949 IGNORE_RET(sys_unlink(info.filename)); | 907 IGNORE_RET(sys_unlink(info.filename)); |
950 #if defined(ADDRESS_SANITIZER) | |
951 IGNORE_RET(sys_unlink(info.log_filename)); | |
952 #endif | |
953 IGNORE_RET(sys_unlink(temp_file)); | 908 IGNORE_RET(sys_unlink(temp_file)); |
954 sys__exit(0); | 909 sys__exit(0); |
955 } | 910 } |
956 | 911 |
957 // Main browser process. | 912 // Main browser process. |
958 if (child <= 0) | 913 if (child <= 0) |
959 return; | 914 return; |
960 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); | 915 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); |
961 } | 916 } |
962 | 917 |
(...skipping 10 matching lines...) Expand all Loading... |
973 const unsigned dump_path_len = my_strlen(dump_path); | 928 const unsigned dump_path_len = my_strlen(dump_path); |
974 const unsigned minidump_id_len = my_strlen(minidump_id); | 929 const unsigned minidump_id_len = my_strlen(minidump_id); |
975 char* const path = reinterpret_cast<char*>(allocator.Alloc( | 930 char* const path = reinterpret_cast<char*>(allocator.Alloc( |
976 dump_path_len + 1 /* '/' */ + minidump_id_len + | 931 dump_path_len + 1 /* '/' */ + minidump_id_len + |
977 4 /* ".dmp" */ + 1 /* NUL */)); | 932 4 /* ".dmp" */ + 1 /* NUL */)); |
978 memcpy(path, dump_path, dump_path_len); | 933 memcpy(path, dump_path, dump_path_len); |
979 path[dump_path_len] = '/'; | 934 path[dump_path_len] = '/'; |
980 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); | 935 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); |
981 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); | 936 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); |
982 path[dump_path_len + 1 + minidump_id_len + 4] = 0; | 937 path[dump_path_len + 1 + minidump_id_len + 4] = 0; |
983 char* const log_path = reinterpret_cast<char*>(allocator.Alloc( | |
984 dump_path_len + 1 /* '/' */ + minidump_id_len + | |
985 4 /* ".log" */ + 1 /* NUL */)); | |
986 memcpy(log_path, path, dump_path_len + 1 + minidump_id_len + 4); | |
987 memcpy(log_path + dump_path_len + 1 + minidump_id_len, ".log", 4); | |
988 | 938 |
989 BreakpadInfo info; | 939 BreakpadInfo info; |
990 info.filename = path; | 940 info.filename = path; |
991 info.log_filename = log_path; | |
992 info.process_type = "browser"; | 941 info.process_type = "browser"; |
993 info.process_type_length = 7; | 942 info.process_type_length = 7; |
994 info.crash_url = NULL; | 943 info.crash_url = NULL; |
995 info.crash_url_length = 0; | 944 info.crash_url_length = 0; |
996 info.guid = child_process_logging::g_client_id; | 945 info.guid = child_process_logging::g_client_id; |
997 info.guid_length = my_strlen(child_process_logging::g_client_id); | 946 info.guid_length = my_strlen(child_process_logging::g_client_id); |
998 info.distro = base::g_linux_distro; | 947 info.distro = base::g_linux_distro; |
999 info.distro_length = my_strlen(base::g_linux_distro); | 948 info.distro_length = my_strlen(base::g_linux_distro); |
1000 info.upload = upload; | 949 info.upload = upload; |
1001 info.process_start_time = g_process_start_time; | 950 info.process_start_time = g_process_start_time; |
(...skipping 14 matching lines...) Expand all Loading... |
1016 #if !defined(OS_ANDROID) | 965 #if !defined(OS_ANDROID) |
1017 // Wrapper function, do not add more code here. | 966 // Wrapper function, do not add more code here. |
1018 static bool CrashDoneUpload(const char* dump_path, | 967 static bool CrashDoneUpload(const char* dump_path, |
1019 const char* minidump_id, | 968 const char* minidump_id, |
1020 void* context, | 969 void* context, |
1021 bool succeeded) { | 970 bool succeeded) { |
1022 return CrashDone(dump_path, minidump_id, true, succeeded); | 971 return CrashDone(dump_path, minidump_id, true, succeeded); |
1023 } | 972 } |
1024 #endif | 973 #endif |
1025 | 974 |
1026 extern "C" | |
1027 void __asan_set_error_report_callback(void (*cb)(const char*)); | |
1028 | |
1029 extern "C" | |
1030 void AsanLinuxBreakpadCallback(const char* report) { | |
1031 g_asan_report_str = const_cast<char*>(report); | |
1032 // Send minidump here. | |
1033 siginfo_t siginfo; | |
1034 my_memset(&siginfo, 0, sizeof(siginfo_t)); | |
1035 struct ucontext context; | |
1036 getcontext(&context); | |
1037 g_breakpad->HandleSignal(9, &siginfo, &context); | |
1038 } | |
1039 | |
1040 static void EnableCrashDumping(bool unattended) { | 975 static void EnableCrashDumping(bool unattended) { |
1041 g_is_crash_reporter_enabled = true; | 976 g_is_crash_reporter_enabled = true; |
1042 | 977 |
1043 FilePath tmp_path("/tmp"); | 978 FilePath tmp_path("/tmp"); |
1044 PathService::Get(base::DIR_TEMP, &tmp_path); | 979 PathService::Get(base::DIR_TEMP, &tmp_path); |
1045 | 980 |
1046 FilePath dumps_path(tmp_path); | 981 FilePath dumps_path(tmp_path); |
1047 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | 982 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { |
1048 FilePath logfile = | 983 FilePath logfile = |
1049 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); | 984 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 char b; // Dummy variable for sys_read below. | 1042 char b; // Dummy variable for sys_read below. |
1108 const char* b_addr = &b; // Get the address of |b| so we can create the | 1043 const char* b_addr = &b; // Get the address of |b| so we can create the |
1109 // expected /proc/[pid]/syscall content in the | 1044 // expected /proc/[pid]/syscall content in the |
1110 // browser to convert namespace tids. | 1045 // browser to convert namespace tids. |
1111 | 1046 |
1112 // The length of the control message: | 1047 // The length of the control message: |
1113 static const unsigned kControlMsgSize = sizeof(fds); | 1048 static const unsigned kControlMsgSize = sizeof(fds); |
1114 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); | 1049 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); |
1115 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); | 1050 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); |
1116 | 1051 |
1117 #if !defined(ADDRESS_SANITIZER) | |
1118 const size_t kIovSize = 8; | 1052 const size_t kIovSize = 8; |
1119 #else | |
1120 // Additional field to pass the AddressSanitizer log to the crash handler. | |
1121 const size_t kIovSize = 9; | |
1122 #endif | |
1123 struct kernel_msghdr msg; | 1053 struct kernel_msghdr msg; |
1124 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); | 1054 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); |
1125 struct kernel_iovec iov[kIovSize]; | 1055 struct kernel_iovec iov[kIovSize]; |
1126 iov[0].iov_base = const_cast<void*>(crash_context); | 1056 iov[0].iov_base = const_cast<void*>(crash_context); |
1127 iov[0].iov_len = crash_context_size; | 1057 iov[0].iov_len = crash_context_size; |
1128 iov[1].iov_base = guid; | 1058 iov[1].iov_base = guid; |
1129 iov[1].iov_len = kGuidSize + 1; | 1059 iov[1].iov_len = kGuidSize + 1; |
1130 iov[2].iov_base = crash_url; | 1060 iov[2].iov_base = crash_url; |
1131 iov[2].iov_len = kMaxActiveURLSize + 1; | 1061 iov[2].iov_len = kMaxActiveURLSize + 1; |
1132 iov[3].iov_base = distro; | 1062 iov[3].iov_base = distro; |
1133 iov[3].iov_len = kDistroSize + 1; | 1063 iov[3].iov_len = kDistroSize + 1; |
1134 iov[4].iov_base = &b_addr; | 1064 iov[4].iov_base = &b_addr; |
1135 iov[4].iov_len = sizeof(b_addr); | 1065 iov[4].iov_len = sizeof(b_addr); |
1136 iov[5].iov_base = &fds[0]; | 1066 iov[5].iov_base = &fds[0]; |
1137 iov[5].iov_len = sizeof(fds[0]); | 1067 iov[5].iov_len = sizeof(fds[0]); |
1138 iov[6].iov_base = &g_process_start_time; | 1068 iov[6].iov_base = &g_process_start_time; |
1139 iov[6].iov_len = sizeof(g_process_start_time); | 1069 iov[6].iov_len = sizeof(g_process_start_time); |
1140 iov[7].iov_base = &base::g_oom_size; | 1070 iov[7].iov_base = &base::g_oom_size; |
1141 iov[7].iov_len = sizeof(base::g_oom_size); | 1071 iov[7].iov_len = sizeof(base::g_oom_size); |
1142 #if defined(ADDRESS_SANITIZER) | |
1143 iov[8].iov_base = g_asan_report_str; | |
1144 iov[8].iov_len = kMaxAsanReportSize + 1; | |
1145 #endif | |
1146 | 1072 |
1147 msg.msg_iov = iov; | 1073 msg.msg_iov = iov; |
1148 msg.msg_iovlen = kIovSize; | 1074 msg.msg_iovlen = kIovSize; |
1149 char cmsg[kControlMsgSpaceSize]; | 1075 char cmsg[kControlMsgSpaceSize]; |
1150 my_memset(cmsg, 0, kControlMsgSpaceSize); | 1076 my_memset(cmsg, 0, kControlMsgSpaceSize); |
1151 msg.msg_control = cmsg; | 1077 msg.msg_control = cmsg; |
1152 msg.msg_controllen = sizeof(cmsg); | 1078 msg.msg_controllen = sizeof(cmsg); |
1153 | 1079 |
1154 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); | 1080 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); |
1155 hdr->cmsg_level = SOL_SOCKET; | 1081 hdr->cmsg_level = SOL_SOCKET; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 } | 1154 } |
1229 | 1155 |
1230 // Set the base process start time value. | 1156 // Set the base process start time value. |
1231 struct timeval tv; | 1157 struct timeval tv; |
1232 if (!gettimeofday(&tv, NULL)) | 1158 if (!gettimeofday(&tv, NULL)) |
1233 g_process_start_time = timeval_to_ms(&tv); | 1159 g_process_start_time = timeval_to_ms(&tv); |
1234 else | 1160 else |
1235 g_process_start_time = 0; | 1161 g_process_start_time = 0; |
1236 | 1162 |
1237 logging::SetDumpWithoutCrashingFunction(&DumpProcess); | 1163 logging::SetDumpWithoutCrashingFunction(&DumpProcess); |
1238 #if defined(ADDRESS_SANITIZER) | |
1239 // Register the callback for AddressSanitizer error reporting. | |
1240 __asan_set_error_report_callback(AsanLinuxBreakpadCallback); | |
1241 #endif | |
1242 } | 1164 } |
1243 | 1165 |
1244 bool IsCrashReporterEnabled() { | 1166 bool IsCrashReporterEnabled() { |
1245 return g_is_crash_reporter_enabled; | 1167 return g_is_crash_reporter_enabled; |
1246 } | 1168 } |
OLD | NEW |