Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(620)

Side by Side Diff: chrome/app/breakpad_linux.cc

Issue 10825329: Rolling the DEPS of Breakpad. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed some breadpad targets Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « breakpad/linux/generate-test-dump.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #define STAT_STRUCT struct kernel_stat 61 #define STAT_STRUCT struct kernel_stat
62 #define FSTAT_FUNC sys_fstat 62 #define FSTAT_FUNC sys_fstat
63 #endif 63 #endif
64 64
65 // 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
66 // 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
67 // 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
68 // spurious compiler warnings. 68 // spurious compiler warnings.
69 #define IGNORE_RET(x) do { if (x); } while (0) 69 #define IGNORE_RET(x) do { if (x); } while (0)
70 70
71 static const char kUploadURL[] = 71 using google_breakpad::ExceptionHandler;
Mark Mentovai 2012/08/14 13:00:19 I don’t think that these using-declarations really
72 "https://clients2.google.com/cr/report"; 72 using google_breakpad::MinidumpDescriptor;
73 73
74 static bool g_is_crash_reporter_enabled = false; 74 namespace {
75 static uint64_t g_process_start_time = 0; 75
76 static char* g_crash_log_path = NULL; 76 const char kUploadURL[] = "https://clients2.google.com/cr/report";
77 static google_breakpad::ExceptionHandler* g_breakpad = NULL; 77
78 bool g_is_crash_reporter_enabled = false;
79 uint64_t g_process_start_time = 0;
80 char* g_crash_log_path = NULL;
81 ExceptionHandler* g_breakpad = NULL;
78 82
79 // Writes the value |v| as 16 hex characters to the memory pointed at by 83 // Writes the value |v| as 16 hex characters to the memory pointed at by
80 // |output|. 84 // |output|.
81 static void write_uint64_hex(char* output, uint64_t v) { 85 void write_uint64_hex(char* output, uint64_t v) {
82 static const char hextable[] = "0123456789abcdef"; 86 static const char hextable[] = "0123456789abcdef";
83 87
84 for (int i = 15; i >= 0; --i) { 88 for (int i = 15; i >= 0; --i) {
85 output[i] = hextable[v & 15]; 89 output[i] = hextable[v & 15];
86 v >>= 4; 90 v >>= 4;
87 } 91 }
88 } 92 }
89 93
90 // The following helper functions are for calculating uptime. 94 // The following helper functions are for calculating uptime.
91 95
92 // Converts a struct timeval to milliseconds. 96 // Converts a struct timeval to milliseconds.
93 static uint64_t timeval_to_ms(struct timeval *tv) { 97 uint64_t timeval_to_ms(struct timeval *tv) {
94 uint64_t ret = tv->tv_sec; // Avoid overflow by explicitly using a uint64_t. 98 uint64_t ret = tv->tv_sec; // Avoid overflow by explicitly using a uint64_t.
95 ret *= 1000; 99 ret *= 1000;
96 ret += tv->tv_usec / 1000; 100 ret += tv->tv_usec / 1000;
97 return ret; 101 return ret;
98 } 102 }
99 103
100 // Converts a struct timeval to milliseconds. 104 // Converts a struct timeval to milliseconds.
101 static uint64_t kernel_timeval_to_ms(struct kernel_timeval *tv) { 105 uint64_t kernel_timeval_to_ms(struct kernel_timeval *tv) {
102 uint64_t ret = tv->tv_sec; // Avoid overflow by explicitly using a uint64_t. 106 uint64_t ret = tv->tv_sec; // Avoid overflow by explicitly using a uint64_t.
103 ret *= 1000; 107 ret *= 1000;
104 ret += tv->tv_usec / 1000; 108 ret += tv->tv_usec / 1000;
105 return ret; 109 return ret;
106 } 110 }
107 111
108 // String buffer size to use to convert a uint64_t to string. 112 // String buffer size to use to convert a uint64_t to string.
109 static size_t kUint64StringSize = 21; 113 size_t kUint64StringSize = 21;
110 114
111 // uint64_t version of my_int_len() from 115 // uint64_t version of my_int_len() from
112 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the 116 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the
113 // given, non-negative integer when expressed in base 10. 117 // given, non-negative integer when expressed in base 10.
114 static unsigned my_uint64_len(uint64_t i) { 118 unsigned my_uint64_len(uint64_t i) {
115 if (!i) 119 if (!i)
116 return 1; 120 return 1;
117 121
118 unsigned len = 0; 122 unsigned len = 0;
119 while (i) { 123 while (i) {
120 len++; 124 len++;
121 i /= 10; 125 i /= 10;
122 } 126 }
123 127
124 return len; 128 return len;
125 } 129 }
126 130
127 // uint64_t version of my_itos() from 131 // uint64_t version of my_itos() from
128 // breakpad/src/common/linux/linux_libc_support.h. Convert a non-negative 132 // breakpad/src/common/linux/linux_libc_support.h. Convert a non-negative
129 // integer to a string (not null-terminated). 133 // integer to a string (not null-terminated).
130 static void my_uint64tos(char* output, uint64_t i, unsigned i_len) { 134 void my_uint64tos(char* output, uint64_t i, unsigned i_len) {
131 for (unsigned index = i_len; index; --index, i /= 10) 135 for (unsigned index = i_len; index; --index, i /= 10)
132 output[index - 1] = '0' + (i % 10); 136 output[index - 1] = '0' + (i % 10);
133 } 137 }
134 138
135 #if defined(OS_ANDROID) 139 #if defined(OS_ANDROID)
136 static char* my_strncpy(char* dst, const char* src, size_t len) { 140 char* my_strncpy(char* dst, const char* src, size_t len) {
137 int i = len; 141 int i = len;
138 char* p = dst; 142 char* p = dst;
139 if (!dst || !src) 143 if (!dst || !src)
140 return dst; 144 return dst;
141 while (i != 0 && *src != '\0') { 145 while (i != 0 && *src != '\0') {
142 *p++ = *src++; 146 *p++ = *src++;
143 i--; 147 i--;
144 } 148 }
145 while (i != 0) { 149 while (i != 0) {
146 *p++ = '\0'; 150 *p++ = '\0';
147 i--; 151 i--;
148 } 152 }
149 return dst; 153 return dst;
150 } 154 }
151 155
152 static char* my_strncat(char *dest, const char* src, size_t len) { 156 char* my_strncat(char *dest, const char* src, size_t len) {
153 char* ret = dest; 157 char* ret = dest;
154 while (*dest) 158 while (*dest)
155 dest++; 159 dest++;
156 while (len--) 160 while (len--)
157 if (!(*dest++ = *src++)) 161 if (!(*dest++ = *src++))
158 return ret; 162 return ret;
159 *dest = 0; 163 *dest = 0;
160 return ret; 164 return ret;
161 } 165 }
162 #endif 166 #endif
163 167
164 namespace {
165
166 // MIME substrings. 168 // MIME substrings.
167 const char g_rn[] = "\r\n"; 169 const char g_rn[] = "\r\n";
168 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; 170 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\"";
169 const char g_quote_msg[] = "\""; 171 const char g_quote_msg[] = "\"";
170 const char g_dashdash_msg[] = "--"; 172 const char g_dashdash_msg[] = "--";
171 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; 173 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\"";
172 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; 174 const char g_content_type_msg[] = "Content-Type: application/octet-stream";
173 175
174 // MimeWriter manages an iovec for writing MIMEs to a file. 176 // MimeWriter manages an iovec for writing MIMEs to a file.
175 class MimeWriter { 177 class MimeWriter {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 const char kGoogleBreakpad[] = "google-breakpad"; 352 const char kGoogleBreakpad[] = "google-breakpad";
351 353
352 size_t WriteLog(const char* buf, size_t nbytes) { 354 size_t WriteLog(const char* buf, size_t nbytes) {
353 #if defined(OS_ANDROID) 355 #if defined(OS_ANDROID)
354 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); 356 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf);
355 #else 357 #else
356 return sys_write(2, buf, nbytes); 358 return sys_write(2, buf, nbytes);
357 #endif 359 #endif
358 } 360 }
359 361
362
363 bool CrashDone(const MinidumpDescriptor& minidump,
364 const bool upload,
365 const bool succeeded) {
366 // WARNING: this code runs in a compromised context. It may not call into
367 // libc nor allocate memory normally.
368 if (!succeeded)
369 return false;
370
371 DCHECK(!minidump.IsFD());
372
373 BreakpadInfo info;
374 info.filename = minidump.path();
375 info.process_type = "browser";
376 info.process_type_length = 7;
377 info.crash_url = NULL;
378 info.crash_url_length = 0;
379 info.guid = child_process_logging::g_client_id;
380 info.guid_length = my_strlen(child_process_logging::g_client_id);
381 info.distro = base::g_linux_distro;
382 info.distro_length = my_strlen(base::g_linux_distro);
383 info.upload = upload;
384 info.process_start_time = g_process_start_time;
385 info.oom_size = base::g_oom_size;
386 info.pid = 0;
387 HandleCrashDump(info);
388 return true;
389 }
390
391 // Wrapper function, do not add more code here.
392 bool CrashDoneNoUpload(const MinidumpDescriptor& minidump,
393 void* context,
394 bool succeeded) {
395 return CrashDone(minidump, false, succeeded);
396 }
397
398 #if !defined(OS_ANDROID)
399 // Wrapper function, do not add more code here.
400 bool CrashDoneUpload(const MinidumpDescriptor& minidump,
401 void* context,
402 bool succeeded) {
403 return CrashDone(minidump, true, succeeded);
404 }
405 #endif
406
407 void EnableCrashDumping(bool unattended) {
408 g_is_crash_reporter_enabled = true;
409
410 FilePath tmp_path("/tmp");
411 PathService::Get(base::DIR_TEMP, &tmp_path);
412
413 FilePath dumps_path(tmp_path);
414 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) {
415 FilePath logfile =
416 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename);
417 std::string logfile_str = logfile.value();
418 const size_t crash_log_path_len = logfile_str.size() + 1;
419 g_crash_log_path = new char[crash_log_path_len];
420 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len);
421 }
422 DCHECK(!g_breakpad);
423 #if defined(OS_ANDROID)
424 unattended = true; // Android never uploads directly.
425 #endif
426 if (unattended) {
427 g_breakpad = new ExceptionHandler(
428 MinidumpDescriptor(dumps_path.value()),
429 NULL,
430 CrashDoneNoUpload,
431 NULL,
432 true, // Install handlers.
433 -1); // Server file descriptor. -1 for in-process.
434 return;
435 }
436
437 #if !defined(OS_ANDROID)
438 // Attended mode
439 g_breakpad = new ExceptionHandler(
440 MinidumpDescriptor(dumps_path.value()),
441 NULL,
442 CrashDoneUpload,
443 NULL,
444 true, // Install handlers.
445 -1); // Server file descriptor. -1 for in-process.
446 #endif
447 }
448
449 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer
450 bool NonBrowserCrashHandler(const void* crash_context,
451 size_t crash_context_size,
452 void* context) {
453 const int fd = reinterpret_cast<intptr_t>(context);
454 int fds[2] = { -1, -1 };
455 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
456 static const char msg[] = "Failed to create socket for crash dumping.\n";
457 WriteLog(msg, sizeof(msg)-1);
458 return false;
459 }
460
461 // Start constructing the message to send to the browser.
462 char guid[kGuidSize + 1] = {0};
463 char crash_url[kMaxActiveURLSize + 1] = {0};
464 char distro[kDistroSize + 1] = {0};
465 const size_t guid_len =
466 std::min(my_strlen(child_process_logging::g_client_id), kGuidSize);
467 const size_t crash_url_len =
468 std::min(my_strlen(child_process_logging::g_active_url),
469 kMaxActiveURLSize);
470 const size_t distro_len =
471 std::min(my_strlen(base::g_linux_distro), kDistroSize);
472 memcpy(guid, child_process_logging::g_client_id, guid_len);
473 memcpy(crash_url, child_process_logging::g_active_url, crash_url_len);
474 memcpy(distro, base::g_linux_distro, distro_len);
475
476 char b; // Dummy variable for sys_read below.
477 const char* b_addr = &b; // Get the address of |b| so we can create the
478 // expected /proc/[pid]/syscall content in the
479 // browser to convert namespace tids.
480
481 // The length of the control message:
482 static const unsigned kControlMsgSize = sizeof(fds);
483 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
484 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
485
486 const size_t kIovSize = 8;
487 struct kernel_msghdr msg;
488 my_memset(&msg, 0, sizeof(struct kernel_msghdr));
489 struct kernel_iovec iov[kIovSize];
490 iov[0].iov_base = const_cast<void*>(crash_context);
491 iov[0].iov_len = crash_context_size;
492 iov[1].iov_base = guid;
493 iov[1].iov_len = kGuidSize + 1;
494 iov[2].iov_base = crash_url;
495 iov[2].iov_len = kMaxActiveURLSize + 1;
496 iov[3].iov_base = distro;
497 iov[3].iov_len = kDistroSize + 1;
498 iov[4].iov_base = &b_addr;
499 iov[4].iov_len = sizeof(b_addr);
500 iov[5].iov_base = &fds[0];
501 iov[5].iov_len = sizeof(fds[0]);
502 iov[6].iov_base = &g_process_start_time;
503 iov[6].iov_len = sizeof(g_process_start_time);
504 iov[7].iov_base = &base::g_oom_size;
505 iov[7].iov_len = sizeof(base::g_oom_size);
506
507 msg.msg_iov = iov;
508 msg.msg_iovlen = kIovSize;
509 char cmsg[kControlMsgSpaceSize];
510 my_memset(cmsg, 0, kControlMsgSpaceSize);
511 msg.msg_control = cmsg;
512 msg.msg_controllen = sizeof(cmsg);
513
514 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
515 hdr->cmsg_level = SOL_SOCKET;
516 hdr->cmsg_type = SCM_RIGHTS;
517 hdr->cmsg_len = kControlMsgLenSize;
518 ((int*) CMSG_DATA(hdr))[0] = fds[0];
519 ((int*) CMSG_DATA(hdr))[1] = fds[1];
520
521 if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) {
522 static const char errmsg[] = "Failed to tell parent about crash.\n";
523 WriteLog(errmsg, sizeof(errmsg)-1);
524 IGNORE_RET(sys_close(fds[1]));
525 return false;
526 }
527 IGNORE_RET(sys_close(fds[1]));
528
529 if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) {
530 static const char errmsg[] = "Parent failed to complete crash dump.\n";
531 WriteLog(errmsg, sizeof(errmsg)-1);
532 }
533
534 return true;
535 }
536
537 void EnableNonBrowserCrashDumping() {
538 const int fd = base::GlobalDescriptors::GetInstance()->Get(kCrashDumpSignal);
539 g_is_crash_reporter_enabled = true;
540 // We deliberately leak this object.
541 DCHECK(!g_breakpad);
542 g_breakpad = new ExceptionHandler(
543 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert.
544 NULL,
545 NULL,
546 reinterpret_cast<void*>(fd), // Param passed to the crash handler.
547 true,
548 -1);
549 g_breakpad->set_crash_handler(NonBrowserCrashHandler);
550 }
551
360 } // namespace 552 } // namespace
361 553
362 void HandleCrashDump(const BreakpadInfo& info) { 554 void HandleCrashDump(const BreakpadInfo& info) {
363 // WARNING: this code runs in a compromised context. It may not call into 555 // WARNING: this code runs in a compromised context. It may not call into
364 // libc nor allocate memory normally. 556 // libc nor allocate memory normally.
365 557
366 const int dumpfd = sys_open(info.filename, O_RDONLY, 0); 558 const int dumpfd = sys_open(info.filename, O_RDONLY, 0);
367 if (dumpfd < 0) { 559 if (dumpfd < 0) {
368 static const char msg[] = "Cannot upload crash dump: failed to open\n"; 560 static const char msg[] = "Cannot upload crash dump: failed to open\n";
369 WriteLog(msg, sizeof(msg)); 561 WriteLog(msg, sizeof(msg));
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 IGNORE_RET(sys_unlink(temp_file)); 1100 IGNORE_RET(sys_unlink(temp_file));
909 sys__exit(0); 1101 sys__exit(0);
910 } 1102 }
911 1103
912 // Main browser process. 1104 // Main browser process.
913 if (child <= 0) 1105 if (child <= 0)
914 return; 1106 return;
915 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); 1107 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0));
916 } 1108 }
917 1109
918 static bool CrashDone(const char* dump_path,
919 const char* minidump_id,
920 const bool upload,
921 const bool succeeded) {
922 // WARNING: this code runs in a compromised context. It may not call into
923 // libc nor allocate memory normally.
924 if (!succeeded)
925 return false;
926
927 google_breakpad::PageAllocator allocator;
928 const unsigned dump_path_len = my_strlen(dump_path);
929 const unsigned minidump_id_len = my_strlen(minidump_id);
930 char* const path = reinterpret_cast<char*>(allocator.Alloc(
931 dump_path_len + 1 /* '/' */ + minidump_id_len +
932 4 /* ".dmp" */ + 1 /* NUL */));
933 memcpy(path, dump_path, dump_path_len);
934 path[dump_path_len] = '/';
935 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len);
936 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4);
937 path[dump_path_len + 1 + minidump_id_len + 4] = 0;
938
939 BreakpadInfo info;
940 info.filename = path;
941 info.process_type = "browser";
942 info.process_type_length = 7;
943 info.crash_url = NULL;
944 info.crash_url_length = 0;
945 info.guid = child_process_logging::g_client_id;
946 info.guid_length = my_strlen(child_process_logging::g_client_id);
947 info.distro = base::g_linux_distro;
948 info.distro_length = my_strlen(base::g_linux_distro);
949 info.upload = upload;
950 info.process_start_time = g_process_start_time;
951 info.oom_size = base::g_oom_size;
952 info.pid = 0;
953 HandleCrashDump(info);
954 return true;
955 }
956
957 // Wrapper function, do not add more code here.
958 static bool CrashDoneNoUpload(const char* dump_path,
959 const char* minidump_id,
960 void* context,
961 bool succeeded) {
962 return CrashDone(dump_path, minidump_id, false, succeeded);
963 }
964
965 #if !defined(OS_ANDROID)
966 // Wrapper function, do not add more code here.
967 static bool CrashDoneUpload(const char* dump_path,
968 const char* minidump_id,
969 void* context,
970 bool succeeded) {
971 return CrashDone(dump_path, minidump_id, true, succeeded);
972 }
973 #endif
974
975 static void EnableCrashDumping(bool unattended) {
976 g_is_crash_reporter_enabled = true;
977
978 FilePath tmp_path("/tmp");
979 PathService::Get(base::DIR_TEMP, &tmp_path);
980
981 FilePath dumps_path(tmp_path);
982 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) {
983 FilePath logfile =
984 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename);
985 std::string logfile_str = logfile.value();
986 const size_t crash_log_path_len = logfile_str.size() + 1;
987 g_crash_log_path = new char[crash_log_path_len];
988 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len);
989 }
990 DCHECK(!g_breakpad);
991 #if defined(OS_ANDROID)
992 unattended = true; // Android never uploads directly.
993 #endif
994 if (unattended) {
995 g_breakpad = new google_breakpad::ExceptionHandler(
996 dumps_path.value().c_str(),
997 NULL,
998 CrashDoneNoUpload,
999 NULL,
1000 true /* install handlers */);
1001 return;
1002 }
1003
1004 #if !defined(OS_ANDROID)
1005 // Attended mode
1006 g_breakpad = new google_breakpad::ExceptionHandler(
1007 tmp_path.value().c_str(),
1008 NULL,
1009 CrashDoneUpload,
1010 NULL,
1011 true /* install handlers */);
1012 #endif
1013 }
1014
1015 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer
1016 static bool NonBrowserCrashHandler(const void* crash_context,
1017 size_t crash_context_size,
1018 void* context) {
1019 const int fd = reinterpret_cast<intptr_t>(context);
1020 int fds[2] = { -1, -1 };
1021 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
1022 static const char msg[] = "Failed to create socket for crash dumping.\n";
1023 WriteLog(msg, sizeof(msg)-1);
1024 return false;
1025 }
1026
1027 // Start constructing the message to send to the browser.
1028 char guid[kGuidSize + 1] = {0};
1029 char crash_url[kMaxActiveURLSize + 1] = {0};
1030 char distro[kDistroSize + 1] = {0};
1031 const size_t guid_len =
1032 std::min(my_strlen(child_process_logging::g_client_id), kGuidSize);
1033 const size_t crash_url_len =
1034 std::min(my_strlen(child_process_logging::g_active_url),
1035 kMaxActiveURLSize);
1036 const size_t distro_len =
1037 std::min(my_strlen(base::g_linux_distro), kDistroSize);
1038 memcpy(guid, child_process_logging::g_client_id, guid_len);
1039 memcpy(crash_url, child_process_logging::g_active_url, crash_url_len);
1040 memcpy(distro, base::g_linux_distro, distro_len);
1041
1042 char b; // Dummy variable for sys_read below.
1043 const char* b_addr = &b; // Get the address of |b| so we can create the
1044 // expected /proc/[pid]/syscall content in the
1045 // browser to convert namespace tids.
1046
1047 // The length of the control message:
1048 static const unsigned kControlMsgSize = sizeof(fds);
1049 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
1050 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
1051
1052 const size_t kIovSize = 8;
1053 struct kernel_msghdr msg;
1054 my_memset(&msg, 0, sizeof(struct kernel_msghdr));
1055 struct kernel_iovec iov[kIovSize];
1056 iov[0].iov_base = const_cast<void*>(crash_context);
1057 iov[0].iov_len = crash_context_size;
1058 iov[1].iov_base = guid;
1059 iov[1].iov_len = kGuidSize + 1;
1060 iov[2].iov_base = crash_url;
1061 iov[2].iov_len = kMaxActiveURLSize + 1;
1062 iov[3].iov_base = distro;
1063 iov[3].iov_len = kDistroSize + 1;
1064 iov[4].iov_base = &b_addr;
1065 iov[4].iov_len = sizeof(b_addr);
1066 iov[5].iov_base = &fds[0];
1067 iov[5].iov_len = sizeof(fds[0]);
1068 iov[6].iov_base = &g_process_start_time;
1069 iov[6].iov_len = sizeof(g_process_start_time);
1070 iov[7].iov_base = &base::g_oom_size;
1071 iov[7].iov_len = sizeof(base::g_oom_size);
1072
1073 msg.msg_iov = iov;
1074 msg.msg_iovlen = kIovSize;
1075 char cmsg[kControlMsgSpaceSize];
1076 my_memset(cmsg, 0, kControlMsgSpaceSize);
1077 msg.msg_control = cmsg;
1078 msg.msg_controllen = sizeof(cmsg);
1079
1080 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
1081 hdr->cmsg_level = SOL_SOCKET;
1082 hdr->cmsg_type = SCM_RIGHTS;
1083 hdr->cmsg_len = kControlMsgLenSize;
1084 ((int*) CMSG_DATA(hdr))[0] = fds[0];
1085 ((int*) CMSG_DATA(hdr))[1] = fds[1];
1086
1087 if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) {
1088 static const char errmsg[] = "Failed to tell parent about crash.\n";
1089 WriteLog(errmsg, sizeof(errmsg)-1);
1090 IGNORE_RET(sys_close(fds[1]));
1091 return false;
1092 }
1093 IGNORE_RET(sys_close(fds[1]));
1094
1095 if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) {
1096 static const char errmsg[] = "Parent failed to complete crash dump.\n";
1097 WriteLog(errmsg, sizeof(errmsg)-1);
1098 }
1099
1100 return true;
1101 }
1102
1103 static void EnableNonBrowserCrashDumping() {
1104 const int fd = base::GlobalDescriptors::GetInstance()->Get(kCrashDumpSignal);
1105 g_is_crash_reporter_enabled = true;
1106 // We deliberately leak this object.
1107 DCHECK(!g_breakpad);
1108 g_breakpad = new google_breakpad::ExceptionHandler(
1109 "" /* unused */, NULL, NULL, reinterpret_cast<void*>(fd), true);
1110 g_breakpad->set_crash_handler(NonBrowserCrashHandler);
1111 }
1112
1113 void InitCrashReporter() { 1110 void InitCrashReporter() {
1114 #if defined(OS_ANDROID) 1111 #if defined(OS_ANDROID)
1115 // This will guarantee that the BuildInfo has been initialized and subsequent 1112 // This will guarantee that the BuildInfo has been initialized and subsequent
1116 // calls will not require memory allocation. 1113 // calls will not require memory allocation.
1117 base::android::BuildInfo::GetInstance(); 1114 base::android::BuildInfo::GetInstance();
1118 #endif 1115 #endif
1119 // Determine the process type and take appropriate action. 1116 // Determine the process type and take appropriate action.
1120 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 1117 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
1121 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) 1118 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad))
1122 return; 1119 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 g_process_start_time = timeval_to_ms(&tv); 1156 g_process_start_time = timeval_to_ms(&tv);
1160 else 1157 else
1161 g_process_start_time = 0; 1158 g_process_start_time = 0;
1162 1159
1163 logging::SetDumpWithoutCrashingFunction(&DumpProcess); 1160 logging::SetDumpWithoutCrashingFunction(&DumpProcess);
1164 } 1161 }
1165 1162
1166 bool IsCrashReporterEnabled() { 1163 bool IsCrashReporterEnabled() {
1167 return g_is_crash_reporter_enabled; 1164 return g_is_crash_reporter_enabled;
1168 } 1165 }
OLDNEW
« no previous file with comments | « breakpad/linux/generate-test-dump.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698