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/crash/content/app/breakpad_linux.h" | 8 #include "components/crash/content/app/breakpad_linux.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 | 93 |
| 94 bool g_is_crash_reporter_enabled = false; | 94 bool g_is_crash_reporter_enabled = false; |
| 95 uint64_t g_process_start_time = 0; | 95 uint64_t g_process_start_time = 0; |
| 96 pid_t g_pid = 0; | 96 pid_t g_pid = 0; |
| 97 char* g_crash_log_path = nullptr; | 97 char* g_crash_log_path = nullptr; |
| 98 ExceptionHandler* g_breakpad = nullptr; | 98 ExceptionHandler* g_breakpad = nullptr; |
| 99 | 99 |
| 100 #if defined(ADDRESS_SANITIZER) | 100 #if defined(ADDRESS_SANITIZER) |
| 101 const char* g_asan_report_str = nullptr; | 101 const char* g_asan_report_str = nullptr; |
| 102 #endif | 102 #endif |
| 103 | |
| 103 #if defined(OS_ANDROID) | 104 #if defined(OS_ANDROID) |
| 104 #define G_DUMPS_SUPPRESSED_MAGIC 0x5AFECEDE | 105 #define G_DUMPS_SUPPRESSED_MAGIC 0x5AFECEDE |
| 105 uint32_t g_dumps_suppressed = 0; | 106 uint32_t g_dumps_suppressed = 0; |
| 106 char* g_process_type = nullptr; | 107 char* g_process_type = nullptr; |
| 107 ExceptionHandler* g_microdump = nullptr; | 108 ExceptionHandler* g_microdump = nullptr; |
| 108 int g_signal_code_pipe_fd = -1; | 109 int g_signal_code_pipe_fd = -1; |
| 109 | 110 |
| 110 class MicrodumpInfo { | 111 class MicrodumpInfo { |
| 111 public: | 112 public: |
| 112 MicrodumpInfo() | 113 MicrodumpInfo() |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1150 | 1151 |
| 1151 if (*fd < 0) { | 1152 if (*fd < 0) { |
| 1152 static const char msg[] = "Cannot upload crash dump: failed to open\n"; | 1153 static const char msg[] = "Cannot upload crash dump: failed to open\n"; |
| 1153 WriteLog(msg, sizeof(msg) - 1); | 1154 WriteLog(msg, sizeof(msg) - 1); |
| 1154 return; | 1155 return; |
| 1155 } | 1156 } |
| 1156 | 1157 |
| 1157 LoadDataFromFD(allocator, *fd, true, file_data, size); | 1158 LoadDataFromFD(allocator, *fd, true, file_data, size); |
| 1158 } | 1159 } |
| 1159 | 1160 |
| 1160 // Spawn the appropriate upload process for the current OS: | 1161 #if defined(OS_CHROMEOS) |
| 1161 // - generic Linux invokes wget. | 1162 |
| 1162 // - ChromeOS invokes crash_reporter. | 1163 // Invoke crash_reporter to notify it of the crash. The actual upload is handled |
| 1164 // by crash_uploader, which runs on a schedule. | |
| 1163 // |dumpfile| is the path to the dump data file. | 1165 // |dumpfile| is the path to the dump data file. |
| 1164 // |mime_boundary| is only used on Linux. | 1166 // |exe_buf| is is the crashing process' name. |
| 1165 // |exe_buf| is only used on CrOS and is the crashing process' name. | 1167 // |status_pipe_fd| is the file descriptor of a pipe that will receive the magic |
| 1166 void ExecUploadProcessOrTerminate(const BreakpadInfo& info, | 1168 // crash complete string. |
| 1169 void UploadWithCrashReporterOrExit(const BreakpadInfo& info, | |
| 1167 const char* dumpfile, | 1170 const char* dumpfile, |
| 1168 const char* mime_boundary, | |
| 1169 const char* exe_buf, | 1171 const char* exe_buf, |
| 1172 int uploader_status_fd, | |
| 1170 google_breakpad::PageAllocator* allocator) { | 1173 google_breakpad::PageAllocator* allocator) { |
| 1171 #if defined(OS_CHROMEOS) | |
| 1172 // CrOS uses crash_reporter instead of wget to report crashes, | 1174 // CrOS uses crash_reporter instead of wget to report crashes, |
| 1173 // it needs to know where the crash dump lives and the pid and uid of the | 1175 // it needs to know where the crash dump lives and the pid and uid of the |
| 1174 // crashing process. | 1176 // crashing process. |
| 1175 static const char kCrashReporterBinary[] = "/sbin/crash_reporter"; | 1177 static const char kCrashReporterBinary[] = "/sbin/crash_reporter"; |
| 1176 | 1178 |
| 1179 // crash_reporter writes output to stdout. Connect it to the status pipe fd. | |
| 1180 if (sys_dup2(uploader_status_fd, STDOUT_FILENO) == -1) { | |
| 1181 const char err[] = "dup2 failed"; | |
| 1182 WriteLog(err, sizeof(err) - 1); | |
| 1183 // Continue anyway, as crash_report may succeed even if we can't read its | |
| 1184 // status. | |
| 1185 } | |
| 1186 | |
| 1177 char pid_buf[kUint64StringSize]; | 1187 char pid_buf[kUint64StringSize]; |
| 1178 uint64_t pid_str_length = my_uint64_len(info.pid); | 1188 uint64_t pid_str_length = my_uint64_len(info.pid); |
| 1179 my_uint64tos(pid_buf, info.pid, pid_str_length); | 1189 my_uint64tos(pid_buf, info.pid, pid_str_length); |
| 1180 pid_buf[pid_str_length] = '\0'; | 1190 pid_buf[pid_str_length] = '\0'; |
| 1181 | 1191 |
| 1182 char uid_buf[kUint64StringSize]; | 1192 char uid_buf[kUint64StringSize]; |
| 1183 uid_t uid = geteuid(); | 1193 uid_t uid = geteuid(); |
| 1184 uint64_t uid_str_length = my_uint64_len(uid); | 1194 uint64_t uid_str_length = my_uint64_len(uid); |
| 1185 my_uint64tos(uid_buf, uid, uid_str_length); | 1195 my_uint64tos(uid_buf, uid, uid_str_length); |
| 1186 uid_buf[uid_str_length] = '\0'; | 1196 uid_buf[uid_str_length] = '\0'; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1216 const char* args[] = { | 1226 const char* args[] = { |
| 1217 kCrashReporterBinary, | 1227 kCrashReporterBinary, |
| 1218 chrome_flag, | 1228 chrome_flag, |
| 1219 pid_flag, | 1229 pid_flag, |
| 1220 uid_flag, | 1230 uid_flag, |
| 1221 exe_flag, | 1231 exe_flag, |
| 1222 nullptr, | 1232 nullptr, |
| 1223 }; | 1233 }; |
| 1224 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1234 static const char msg[] = "Cannot upload crash dump: cannot exec " |
| 1225 "/sbin/crash_reporter\n"; | 1235 "/sbin/crash_reporter\n"; |
| 1226 #else | 1236 execve(args[0], const_cast<char**>(args), environ); |
| 1237 WriteLog(msg, sizeof(msg) - 1); | |
| 1238 sys__exit(1); | |
| 1239 } | |
| 1240 | |
| 1241 #else // defined(OS_CHROMEOS) | |
| 1242 | |
| 1243 // Invoke wget to upload the crash dump. | |
| 1244 // |dumpfile| is the path to the dump data file. | |
| 1245 // |uploader_status_fd| is the file descriptor to which to write the crash id. | |
| 1246 void UploadWithWgetOrExit(const BreakpadInfo& info, | |
| 1247 const char* dumpfile, | |
|
vapier
2017/02/06 17:17:44
indent is off here
James Cook
2017/02/06 22:09:05
Deleted this block.
| |
| 1248 const char* mime_boundary, | |
| 1249 int uploader_status_fd, | |
| 1250 google_breakpad::PageAllocator* allocator) { | |
| 1251 // Configure wget to write to file descriptor 3. Do this before other work | |
|
vapier
2017/02/06 17:17:44
does it really need to dup ? can't it write to /d
James Cook
2017/02/06 22:09:05
Changed to write to /dev/fd/<foo> directly. I extr
| |
| 1252 // that might allocate a file descriptor. | |
| 1253 const int kWgetOutputFd = 3; | |
| 1254 const char kWgetOutputFdPath[] = "/dev/fd/3"; | |
| 1255 if (sys_dup2(uploader_status_fd, kWgetOutputFd) == -1) { | |
| 1256 const char err[] = "dup2 failed"; | |
| 1257 WriteLog(err, sizeof(err) - 1); | |
| 1258 // Continue anyway since wget may succeed even if we can't read its status. | |
| 1259 } | |
| 1260 | |
| 1227 // Compress |dumpfile| with gzip. | 1261 // Compress |dumpfile| with gzip. |
| 1228 const pid_t gzip_child = sys_fork(); | 1262 const pid_t gzip_child = sys_fork(); |
| 1229 if (gzip_child < 0) { | 1263 if (gzip_child < 0) { |
| 1230 static const char msg[] = "sys_fork() for gzip process failed.\n"; | 1264 static const char msg[] = "sys_fork() for gzip process failed.\n"; |
| 1231 WriteLog(msg, sizeof(msg) - 1); | 1265 WriteLog(msg, sizeof(msg) - 1); |
| 1232 sys__exit(1); | 1266 sys__exit(1); |
| 1233 } | 1267 } |
| 1234 if (!gzip_child) { | 1268 if (!gzip_child) { |
| 1235 // gzip process. | 1269 // gzip process. |
| 1236 const char* args[] = { | 1270 const char* args[] = { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 static const char kWgetBinary[] = "/usr/bin/wget"; | 1330 static const char kWgetBinary[] = "/usr/bin/wget"; |
| 1297 const char* args[] = { | 1331 const char* args[] = { |
| 1298 kWgetBinary, | 1332 kWgetBinary, |
| 1299 header_content_encoding, | 1333 header_content_encoding, |
| 1300 header_content_type, | 1334 header_content_type, |
| 1301 post_file, | 1335 post_file, |
| 1302 kUploadURL, | 1336 kUploadURL, |
| 1303 "--timeout=10", // Set a timeout so we don't hang forever. | 1337 "--timeout=10", // Set a timeout so we don't hang forever. |
| 1304 "--tries=1", // Don't retry if the upload fails. | 1338 "--tries=1", // Don't retry if the upload fails. |
| 1305 "-O", // output reply to fd 3 | 1339 "-O", // output reply to fd 3 |
| 1306 "/dev/fd/3", | 1340 kWgetOutputFdPath, |
| 1307 nullptr, | 1341 nullptr, |
| 1308 }; | 1342 }; |
| 1309 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1343 static const char msg[] = "Cannot upload crash dump: cannot exec " |
| 1310 "/usr/bin/wget\n"; | 1344 "/usr/bin/wget\n"; |
| 1311 #endif | |
| 1312 execve(args[0], const_cast<char**>(args), environ); | 1345 execve(args[0], const_cast<char**>(args), environ); |
| 1313 WriteLog(msg, sizeof(msg) - 1); | 1346 WriteLog(msg, sizeof(msg) - 1); |
| 1314 sys__exit(1); | 1347 sys__exit(1); |
| 1315 } | 1348 } |
| 1316 | 1349 |
| 1350 #endif // defined(OS_CHROMEOS) | |
| 1351 | |
| 1317 // Runs in the helper process to wait for the upload process running | 1352 // Runs in the helper process to wait for the upload process running |
| 1318 // ExecUploadProcessOrTerminate() to finish. Returns the number of bytes written | 1353 // ExecUploadProcessOrTerminate() to finish. Returns the number of bytes written |
| 1319 // to |fd| and save the written contents to |buf|. | 1354 // to |fd| and save the written contents to |buf|. |
| 1320 // |buf| needs to be big enough to hold |bytes_to_read| + 1 characters. | 1355 // |buf| needs to be big enough to hold |bytes_to_read| + 1 characters. |
| 1321 size_t WaitForCrashReportUploadProcess(int fd, size_t bytes_to_read, | 1356 size_t WaitForCrashReportUploadProcess(int fd, size_t bytes_to_read, |
| 1322 char* buf) { | 1357 char* buf) { |
| 1323 size_t bytes_read = 0; | 1358 size_t bytes_read = 0; |
| 1324 | 1359 |
| 1325 // Upload should finish in about 10 seconds. Add a few more 500 ms | 1360 // Upload should finish in about 10 seconds. Add a few more 500 ms |
| 1326 // internals to account for process startup time. | 1361 // internals to account for process startup time. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1345 // |ret| == 0 -> timed out, continue waiting. | 1380 // |ret| == 0 -> timed out, continue waiting. |
| 1346 // or |bytes_read| < |bytes_to_read| still, keep reading. | 1381 // or |bytes_read| < |bytes_to_read| still, keep reading. |
| 1347 } | 1382 } |
| 1348 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. | 1383 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. |
| 1349 return bytes_read; | 1384 return bytes_read; |
| 1350 } | 1385 } |
| 1351 | 1386 |
| 1352 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. | 1387 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| 1353 bool IsValidCrashReportId(const char* buf, size_t bytes_read, | 1388 bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
| 1354 size_t expected_len) { | 1389 size_t expected_len) { |
| 1355 if (bytes_read != expected_len) | 1390 if (bytes_read != expected_len) { |
| 1391 static const char msg[] = "Unexpected crash report id length\n"; | |
| 1392 WriteLog(msg, sizeof(msg) - 1); | |
| 1356 return false; | 1393 return false; |
| 1394 } | |
| 1357 #if defined(OS_CHROMEOS) | 1395 #if defined(OS_CHROMEOS) |
| 1396 // See kSuccessMagic in platform2/crash-reporter/chrome_collector.cc. | |
| 1358 return my_strcmp(buf, "_sys_cr_finished") == 0; | 1397 return my_strcmp(buf, "_sys_cr_finished") == 0; |
| 1359 #else | 1398 #else |
| 1360 for (size_t i = 0; i < bytes_read; ++i) { | 1399 for (size_t i = 0; i < bytes_read; ++i) { |
| 1361 if (!my_isxdigit(buf[i])) | 1400 if (!my_isxdigit(buf[i])) |
| 1362 return false; | 1401 return false; |
| 1363 } | 1402 } |
| 1364 return true; | 1403 return true; |
| 1365 #endif | 1404 #endif |
| 1366 } | 1405 } |
| 1367 | 1406 |
| 1368 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. | 1407 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| 1369 void HandleCrashReportId(const char* buf, size_t bytes_read, | 1408 void HandleCrashReportId(const char* buf, size_t bytes_read, |
| 1370 size_t expected_len) { | 1409 size_t expected_len) { |
| 1371 WriteNewline(); | 1410 WriteNewline(); |
| 1372 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { | 1411 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { |
| 1373 #if defined(OS_CHROMEOS) | 1412 #if defined(OS_CHROMEOS) |
| 1374 static const char msg[] = | 1413 static const char msg[] = |
| 1375 "System crash-reporter failed to process crash report."; | 1414 "System crash_reporter failed to process crash report."; |
| 1376 #else | 1415 #else |
| 1377 static const char msg[] = "Failed to get crash dump id."; | 1416 static const char msg[] = "Failed to get crash dump id."; |
| 1378 #endif | 1417 #endif |
| 1379 WriteLog(msg, sizeof(msg) - 1); | 1418 WriteLog(msg, sizeof(msg) - 1); |
| 1380 WriteNewline(); | 1419 WriteNewline(); |
| 1381 | 1420 |
| 1382 static const char id_msg[] = "Report Id: "; | 1421 static const char id_msg[] = "Report Id: "; |
| 1383 WriteLog(id_msg, sizeof(id_msg) - 1); | 1422 WriteLog(id_msg, sizeof(id_msg) - 1); |
| 1384 WriteLog(buf, bytes_read); | 1423 WriteLog(buf, bytes_read); |
| 1385 WriteNewline(); | 1424 WriteNewline(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1440 if (name) | 1479 if (name) |
| 1441 return name + 1; | 1480 return name + 1; |
| 1442 return link; | 1481 return link; |
| 1443 } | 1482 } |
| 1444 } | 1483 } |
| 1445 // Either way too long, or a read error. | 1484 // Either way too long, or a read error. |
| 1446 return "chrome-crash-unknown-process"; | 1485 return "chrome-crash-unknown-process"; |
| 1447 } | 1486 } |
| 1448 #endif | 1487 #endif |
| 1449 | 1488 |
| 1489 // Attempts to close all open file descriptors other than stdin, stdout and | |
|
vapier
2017/02/06 17:17:44
this move doesn't seem related ?
James Cook
2017/02/06 22:09:05
No, but HandleCrashDump() is 400 lines long, so I'
| |
| 1490 // stderr (0, 1, and 2). | |
| 1491 void CloseAllFileDescriptors() { | |
| 1492 const int fd = sys_open("/proc/self/fd", O_DIRECTORY | O_RDONLY, 0); | |
| 1493 if (fd < 0) { | |
| 1494 for (unsigned i = 3; i < 8192; ++i) | |
| 1495 IGNORE_RET(sys_close(i)); | |
| 1496 } else { | |
| 1497 google_breakpad::DirectoryReader reader(fd); | |
| 1498 const char* name; | |
| 1499 while (reader.GetNextEntry(&name)) { | |
| 1500 int i; | |
| 1501 if (my_strtoui(&i, name) && i > 2 && i != fd) | |
| 1502 IGNORE_RET(sys_close(i)); | |
| 1503 reader.PopEntry(); | |
| 1504 } | |
| 1505 | |
| 1506 IGNORE_RET(sys_close(fd)); | |
| 1507 } | |
| 1508 } | |
| 1509 | |
| 1450 void HandleCrashDump(const BreakpadInfo& info) { | 1510 void HandleCrashDump(const BreakpadInfo& info) { |
| 1451 int dumpfd; | 1511 int dumpfd; |
| 1452 bool keep_fd = false; | 1512 bool keep_fd = false; |
| 1453 size_t dump_size; | 1513 size_t dump_size; |
| 1454 uint8_t* dump_data; | 1514 uint8_t* dump_data; |
| 1455 google_breakpad::PageAllocator allocator; | 1515 google_breakpad::PageAllocator allocator; |
| 1456 const char* exe_buf = nullptr; | |
| 1457 | 1516 |
| 1458 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { | 1517 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { |
| 1459 return; | 1518 return; |
| 1460 } | 1519 } |
| 1461 | 1520 |
| 1462 #if defined(OS_CHROMEOS) | 1521 #if defined(OS_CHROMEOS) |
| 1463 // Grab the crashing process' name now, when it should still be available. | 1522 // Grab the crashing process' name now, when it should still be available. |
| 1464 // If we try to do this later in our grandchild the crashing process has | 1523 // If we try to do this later in our grandchild the crashing process has |
| 1465 // already terminated. | 1524 // already terminated. |
| 1466 exe_buf = GetCrashingProcessName(info, &allocator); | 1525 const char* exe_buf = GetCrashingProcessName(info, &allocator); |
| 1467 #endif | 1526 #endif |
| 1468 | 1527 |
| 1469 if (info.fd != -1) { | 1528 if (info.fd != -1) { |
| 1470 // Dump is provided with an open FD. | 1529 // Dump is provided with an open FD. |
| 1471 keep_fd = true; | 1530 keep_fd = true; |
| 1472 dumpfd = info.fd; | 1531 dumpfd = info.fd; |
| 1473 | 1532 |
| 1474 // The FD is pointing to the end of the file. | 1533 // The FD is pointing to the end of the file. |
| 1475 // Rewind, we'll read the data next. | 1534 // Rewind, we'll read the data next. |
| 1476 if (lseek(dumpfd, 0, SEEK_SET) == -1) { | 1535 if (lseek(dumpfd, 0, SEEK_SET) == -1) { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1772 // | 1831 // |
| 1773 // This code is called both when a browser is crashing (in which case, | 1832 // This code is called both when a browser is crashing (in which case, |
| 1774 // nothing really matters any more) and when a renderer/plugin crashes, in | 1833 // nothing really matters any more) and when a renderer/plugin crashes, in |
| 1775 // which case we need to continue. | 1834 // which case we need to continue. |
| 1776 // | 1835 // |
| 1777 // Since we are a multithreaded app, if we were just to fork(), we might | 1836 // Since we are a multithreaded app, if we were just to fork(), we might |
| 1778 // grab file descriptors which have just been created in another thread and | 1837 // grab file descriptors which have just been created in another thread and |
| 1779 // hold them open for too long. | 1838 // hold them open for too long. |
| 1780 // | 1839 // |
| 1781 // Thus, we have to loop and try and close everything. | 1840 // Thus, we have to loop and try and close everything. |
| 1782 const int fd = sys_open("/proc/self/fd", O_DIRECTORY | O_RDONLY, 0); | 1841 CloseAllFileDescriptors(); |
| 1783 if (fd < 0) { | |
| 1784 for (unsigned i = 3; i < 8192; ++i) | |
| 1785 IGNORE_RET(sys_close(i)); | |
| 1786 } else { | |
| 1787 google_breakpad::DirectoryReader reader(fd); | |
| 1788 const char* name; | |
| 1789 while (reader.GetNextEntry(&name)) { | |
| 1790 int i; | |
| 1791 if (my_strtoui(&i, name) && i > 2 && i != fd) | |
| 1792 IGNORE_RET(sys_close(i)); | |
| 1793 reader.PopEntry(); | |
| 1794 } | |
| 1795 | |
| 1796 IGNORE_RET(sys_close(fd)); | |
| 1797 } | |
| 1798 | 1842 |
| 1799 IGNORE_RET(sys_setsid()); | 1843 IGNORE_RET(sys_setsid()); |
| 1800 | 1844 |
| 1801 // Leave one end of a pipe in the upload process and watch for it getting | 1845 // Leave one end of a pipe in the upload process and watch for it getting |
| 1802 // closed by the upload process exiting. | 1846 // closed by the upload process exiting. |
| 1803 int fds[2]; | 1847 int fds[2]; |
| 1804 if (sys_pipe(fds) >= 0) { | 1848 if (sys_pipe(fds) >= 0) { |
| 1805 const pid_t upload_child = sys_fork(); | 1849 const pid_t upload_child = sys_fork(); |
| 1806 if (!upload_child) { | 1850 if (!upload_child) { |
| 1807 // Upload process. | 1851 // Upload process. |
| 1808 IGNORE_RET(sys_close(fds[0])); | 1852 IGNORE_RET(sys_close(fds[0])); // Close read end of pipe. |
| 1809 IGNORE_RET(sys_dup2(fds[1], 3)); | 1853 const int pipe_write_fd = fds[1]; |
| 1810 ExecUploadProcessOrTerminate(info, temp_file, mime_boundary, exe_buf, | 1854 #if defined(OS_CHROMEOS) |
| 1811 &allocator); | 1855 UploadWithCrashReporterOrExit(info, temp_file, exe_buf, pipe_write_fd, |
| 1856 &allocator); | |
| 1857 #else | |
| 1858 UploadWithWgetOrExit(info, temp_file, mime_boundary, pipe_write_fd, | |
| 1859 &allocator); | |
| 1860 #endif | |
| 1812 } | 1861 } |
| 1813 | 1862 |
| 1814 // Helper process. | 1863 // Helper process. |
| 1815 if (upload_child > 0) { | 1864 if (upload_child > 0) { |
| 1816 IGNORE_RET(sys_close(fds[1])); | 1865 IGNORE_RET(sys_close(fds[1])); // Close write end of pipe. |
| 1817 | 1866 |
| 1818 const size_t kCrashIdLength = 16; | 1867 const size_t kCrashIdLength = 16; |
| 1819 char id_buf[kCrashIdLength + 1]; | 1868 char id_buf[kCrashIdLength + 1]; |
| 1820 size_t bytes_read = | 1869 size_t bytes_read = |
| 1821 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); | 1870 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); |
| 1822 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); | 1871 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); |
| 1823 | 1872 |
| 1824 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { | 1873 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { |
| 1825 // Upload process is still around, kill it. | 1874 // Upload process is still around, kill it. |
| 1826 sys_kill(upload_child, SIGKILL); | 1875 sys_kill(upload_child, SIGKILL); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 void SuppressDumpGeneration() { | 2023 void SuppressDumpGeneration() { |
| 1975 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; | 2024 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; |
| 1976 } | 2025 } |
| 1977 #endif // OS_ANDROID | 2026 #endif // OS_ANDROID |
| 1978 | 2027 |
| 1979 bool IsCrashReporterEnabled() { | 2028 bool IsCrashReporterEnabled() { |
| 1980 return g_is_crash_reporter_enabled; | 2029 return g_is_crash_reporter_enabled; |
| 1981 } | 2030 } |
| 1982 | 2031 |
| 1983 } // namespace breakpad | 2032 } // namespace breakpad |
| OLD | NEW |