Chromium Code Reviews| 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/breakpad/app/breakpad_linux.h" | 8 #include "components/breakpad/app/breakpad_linux.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1013 NULL, | 1013 NULL, |
| 1014 }; | 1014 }; |
| 1015 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1015 static const char msg[] = "Cannot upload crash dump: cannot exec " |
| 1016 "/usr/bin/wget\n"; | 1016 "/usr/bin/wget\n"; |
| 1017 #endif | 1017 #endif |
| 1018 execve(args[0], const_cast<char**>(args), environ); | 1018 execve(args[0], const_cast<char**>(args), environ); |
| 1019 WriteLog(msg, sizeof(msg) - 1); | 1019 WriteLog(msg, sizeof(msg) - 1); |
| 1020 sys__exit(1); | 1020 sys__exit(1); |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 bool IsValidCrashReportId(const char* buf, size_t buflen, size_t expected_len) { | |
| 1024 if (buflen != expected_len) | |
| 1025 return false; | |
| 1026 #if defined(OS_CHROMEOS) | |
| 1027 return strcmp(buf, "_sys_cr_finished") == 0; | |
| 1028 #else | |
| 1029 for (size_t i = 0; i < buflen; ++i) { | |
| 1030 char c = buf[i]; | |
|
vapier
2014/04/23 22:03:21
i think you want:
for (size_t i = 0; i < buflen;
Lei Zhang
2014/04/24 00:37:25
We can't call into libc in the middle of a crash.
| |
| 1031 if ((c >= '0' && c <= '9') || (c >= 'a' || c <= 'f')) | |
| 1032 continue; | |
| 1033 return false; | |
| 1034 } | |
| 1035 return true; | |
| 1036 #endif | |
| 1037 } | |
| 1038 | |
| 1023 #if defined(OS_CHROMEOS) | 1039 #if defined(OS_CHROMEOS) |
| 1024 const char* GetCrashingProcessName(const BreakpadInfo& info, | 1040 const char* GetCrashingProcessName(const BreakpadInfo& info, |
| 1025 google_breakpad::PageAllocator* allocator) { | 1041 google_breakpad::PageAllocator* allocator) { |
| 1026 // Symlink to process binary is at /proc/###/exe. | 1042 // Symlink to process binary is at /proc/###/exe. |
| 1027 char linkpath[kUint64StringSize + sizeof("/proc/") + sizeof("/exe")] = | 1043 char linkpath[kUint64StringSize + sizeof("/proc/") + sizeof("/exe")] = |
| 1028 "/proc/"; | 1044 "/proc/"; |
| 1029 uint64_t pid_value_len = my_uint64_len(info.pid); | 1045 uint64_t pid_value_len = my_uint64_len(info.pid); |
| 1030 my_uint64tos(linkpath + sizeof("/proc/") - 1, info.pid, pid_value_len); | 1046 my_uint64tos(linkpath + sizeof("/proc/") - 1, info.pid, pid_value_len); |
| 1031 linkpath[sizeof("/proc/") - 1 + pid_value_len] = '\0'; | 1047 linkpath[sizeof("/proc/") - 1 + pid_value_len] = '\0'; |
| 1032 my_strlcat(linkpath, "/exe", sizeof(linkpath)); | 1048 my_strlcat(linkpath, "/exe", sizeof(linkpath)); |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1402 if (!upload_child) { | 1418 if (!upload_child) { |
| 1403 // Upload process. | 1419 // Upload process. |
| 1404 IGNORE_RET(sys_close(fds[0])); | 1420 IGNORE_RET(sys_close(fds[0])); |
| 1405 IGNORE_RET(sys_dup2(fds[1], 3)); | 1421 IGNORE_RET(sys_dup2(fds[1], 3)); |
| 1406 ExecUploadProcessOrTerminate(info, temp_file, mime_boundary, exe_buf, | 1422 ExecUploadProcessOrTerminate(info, temp_file, mime_boundary, exe_buf, |
| 1407 &allocator); | 1423 &allocator); |
| 1408 } | 1424 } |
| 1409 | 1425 |
| 1410 // Helper process. | 1426 // Helper process. |
| 1411 if (upload_child > 0) { | 1427 if (upload_child > 0) { |
| 1428 const size_t kCrashIdLength = 16; | |
| 1412 IGNORE_RET(sys_close(fds[1])); | 1429 IGNORE_RET(sys_close(fds[1])); |
| 1413 char id_buf[17]; // Crash report IDs are expected to be 16 chars. | 1430 char id_buf[kCrashIdLength + 1]; |
| 1414 ssize_t len = -1; | 1431 size_t bytes_read = 0; |
| 1415 // Upload should finish in about 10 seconds. Add a few more 500 ms | 1432 // Upload should finish in about 10 seconds. Add a few more 500 ms |
| 1416 // internals to account for process startup time. | 1433 // internals to account for process startup time. |
| 1417 for (size_t wait_count = 0; wait_count < 24; ++wait_count) { | 1434 for (size_t wait_count = 0; wait_count < 24; ++wait_count) { |
| 1418 struct kernel_pollfd poll_fd; | 1435 struct kernel_pollfd poll_fd; |
| 1419 poll_fd.fd = fds[0]; | 1436 poll_fd.fd = fds[0]; |
| 1420 poll_fd.events = POLLIN | POLLPRI | POLLERR; | 1437 poll_fd.events = POLLIN | POLLPRI | POLLERR; |
| 1421 int ret = sys_poll(&poll_fd, 1, 500); | 1438 int ret = sys_poll(&poll_fd, 1, 500); |
| 1422 if (ret < 0) { | 1439 if (ret < 0) { |
| 1423 // Error | 1440 // Error |
| 1424 break; | 1441 break; |
| 1425 } else if (ret > 0) { | 1442 } else if (ret > 0) { |
| 1426 // There is data to read. | 1443 // There is data to read. |
| 1427 len = HANDLE_EINTR(sys_read(fds[0], id_buf, sizeof(id_buf) - 1)); | 1444 ssize_t len = HANDLE_EINTR( |
| 1428 break; | 1445 sys_read(fds[0], |
| 1446 &id_buf[bytes_read], | |
| 1447 sizeof(id_buf) - bytes_read - 1)); | |
| 1448 if (len < 0) | |
| 1449 break; | |
| 1450 bytes_read += len; | |
| 1451 if (bytes_read == kCrashIdLength) | |
| 1452 break; | |
| 1429 } | 1453 } |
| 1430 // ret == 0 -> timed out, continue waiting. | 1454 // |ret| == 0 -> timed out, continue waiting. |
| 1455 // or |bytes_read| < |kCrashIdLength| still, keep reading. | |
| 1431 } | 1456 } |
| 1432 if (len > 0) { | 1457 id_buf[kCrashIdLength] = 0; // Always NULL terminate the buffer. |
| 1458 if (IsValidCrashReportId(id_buf, bytes_read, kCrashIdLength)) { | |
| 1433 // Write crash dump id to stderr. | 1459 // Write crash dump id to stderr. |
| 1434 id_buf[len] = 0; | |
| 1435 static const char msg[] = "\nCrash dump id: "; | 1460 static const char msg[] = "\nCrash dump id: "; |
| 1436 WriteLog(msg, sizeof(msg) - 1); | 1461 WriteLog(msg, sizeof(msg) - 1); |
| 1437 WriteLog(id_buf, my_strlen(id_buf)); | 1462 WriteLog(id_buf, my_strlen(id_buf)); |
| 1438 WriteLog("\n", 1); | 1463 WriteLog("\n", 1); |
| 1439 | 1464 |
| 1440 // Write crash dump id to crash log as: seconds_since_epoch,crash_id | 1465 // Write crash dump id to crash log as: seconds_since_epoch,crash_id |
| 1441 struct kernel_timeval tv; | 1466 struct kernel_timeval tv; |
| 1442 if (g_crash_log_path && !sys_gettimeofday(&tv, NULL)) { | 1467 if (g_crash_log_path && !sys_gettimeofday(&tv, NULL)) { |
| 1443 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; | 1468 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; |
| 1444 char time_str[kUint64StringSize]; | 1469 char time_str[kUint64StringSize]; |
| 1445 const unsigned time_len = my_uint64_len(time); | 1470 const unsigned time_len = my_uint64_len(time); |
| 1446 my_uint64tos(time_str, time, time_len); | 1471 my_uint64tos(time_str, time, time_len); |
| 1447 | 1472 |
| 1448 int log_fd = sys_open(g_crash_log_path, | 1473 int log_fd = sys_open(g_crash_log_path, |
| 1449 O_CREAT | O_WRONLY | O_APPEND, | 1474 O_CREAT | O_WRONLY | O_APPEND, |
| 1450 0600); | 1475 0600); |
| 1451 if (log_fd > 0) { | 1476 if (log_fd > 0) { |
| 1452 sys_write(log_fd, time_str, time_len); | 1477 sys_write(log_fd, time_str, time_len); |
| 1453 sys_write(log_fd, ",", 1); | 1478 sys_write(log_fd, ",", 1); |
| 1454 sys_write(log_fd, id_buf, my_strlen(id_buf)); | 1479 sys_write(log_fd, id_buf, my_strlen(id_buf)); |
| 1455 sys_write(log_fd, "\n", 1); | 1480 sys_write(log_fd, "\n", 1); |
| 1456 IGNORE_RET(sys_close(log_fd)); | 1481 IGNORE_RET(sys_close(log_fd)); |
| 1457 } | 1482 } |
| 1458 } | 1483 } |
| 1484 } else { | |
| 1485 static const char msg[] = "\nFailed to get crash dump id.\n"; | |
| 1486 WriteLog(msg, sizeof(msg) - 1); | |
| 1459 } | 1487 } |
| 1488 | |
| 1460 if (sys_waitpid(upload_child, NULL, WNOHANG) == 0) { | 1489 if (sys_waitpid(upload_child, NULL, WNOHANG) == 0) { |
| 1461 // Upload process is still around, kill it. | 1490 // Upload process is still around, kill it. |
| 1462 sys_kill(upload_child, SIGKILL); | 1491 sys_kill(upload_child, SIGKILL); |
| 1463 } | 1492 } |
| 1464 } | 1493 } |
| 1465 } | 1494 } |
| 1466 | 1495 |
| 1467 // Helper process. | 1496 // Helper process. |
| 1468 IGNORE_RET(sys_unlink(info.filename)); | 1497 IGNORE_RET(sys_unlink(info.filename)); |
| 1469 #if defined(ADDRESS_SANITIZER) | 1498 #if defined(ADDRESS_SANITIZER) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1545 } | 1574 } |
| 1546 } | 1575 } |
| 1547 } | 1576 } |
| 1548 #endif // OS_ANDROID | 1577 #endif // OS_ANDROID |
| 1549 | 1578 |
| 1550 bool IsCrashReporterEnabled() { | 1579 bool IsCrashReporterEnabled() { |
| 1551 return g_is_crash_reporter_enabled; | 1580 return g_is_crash_reporter_enabled; |
| 1552 } | 1581 } |
| 1553 | 1582 |
| 1554 } // namespace breakpad | 1583 } // namespace breakpad |
| OLD | NEW |