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 |
| 1161 // Concatenates a |prefix| and a |number| to get a string like "--foo=123" or |
| 1162 // "/dev/fd/4". Safe to run in a compromised context. The returned memory is |
| 1163 // internally owned by |allocator|. |
| 1164 char* StringFromPrefixAndUint(const char* prefix, |
| 1165 uint64_t number, |
| 1166 google_breakpad::PageAllocator* allocator) { |
| 1167 // Convert the number to a string. |
| 1168 char number_buf[kUint64StringSize]; |
| 1169 const unsigned number_len = my_uint64_len(number); |
| 1170 my_uint64tos(number_buf, number, number_len); |
| 1171 number_buf[number_len] = '\0'; |
| 1172 |
| 1173 // Concatenate the prefix and number. |
| 1174 size_t output_len = my_strlen(prefix) + my_strlen(number_buf) + 1; |
| 1175 char* output = reinterpret_cast<char*>(allocator->Alloc(output_len)); |
| 1176 my_strlcpy(output, prefix, output_len); |
| 1177 my_strlcat(output, number_buf, output_len); |
| 1178 return output; |
| 1179 } |
| 1180 |
1160 // Spawn the appropriate upload process for the current OS: | 1181 // Spawn the appropriate upload process for the current OS: |
1161 // - generic Linux invokes wget. | 1182 // - generic Linux invokes wget. |
1162 // - ChromeOS invokes crash_reporter. | 1183 // - Chrome OS invokes crash_reporter. Crashes are uploaded by a separate |
| 1184 // crash_sender script that runs periodically. |
1163 // |dumpfile| is the path to the dump data file. | 1185 // |dumpfile| is the path to the dump data file. |
1164 // |mime_boundary| is only used on Linux. | 1186 // |mime_boundary| is only used on Linux. |
1165 // |exe_buf| is only used on CrOS and is the crashing process' name. | 1187 // |exe_buf| is only used on CrOS and is the crashing process' name. |
| 1188 // |upload_status_fd| is the file descriptor of a pipe that will receive: |
| 1189 // - On Linux, the crash report id |
| 1190 // - On Chrome OS, the magic crash complete string. |
1166 void ExecUploadProcessOrTerminate(const BreakpadInfo& info, | 1191 void ExecUploadProcessOrTerminate(const BreakpadInfo& info, |
1167 const char* dumpfile, | 1192 const char* dumpfile, |
1168 const char* mime_boundary, | 1193 const char* mime_boundary, |
1169 const char* exe_buf, | 1194 const char* exe_buf, |
| 1195 int upload_status_fd, |
1170 google_breakpad::PageAllocator* allocator) { | 1196 google_breakpad::PageAllocator* allocator) { |
1171 #if defined(OS_CHROMEOS) | 1197 #if defined(OS_CHROMEOS) |
1172 // CrOS uses crash_reporter instead of wget to report crashes, | 1198 // 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 | 1199 // it needs to know where the crash dump lives and the pid and uid of the |
1174 // crashing process. | 1200 // crashing process. |
1175 static const char kCrashReporterBinary[] = "/sbin/crash_reporter"; | 1201 static const char kCrashReporterBinary[] = "/sbin/crash_reporter"; |
1176 | 1202 |
1177 char pid_buf[kUint64StringSize]; | 1203 // crash_reporter writes output to stdout. Connect it to the status pipe fd. |
1178 uint64_t pid_str_length = my_uint64_len(info.pid); | 1204 if (sys_dup2(upload_status_fd, STDOUT_FILENO) == -1) { |
1179 my_uint64tos(pid_buf, info.pid, pid_str_length); | 1205 const char err[] = "dup2 failed\n"; |
1180 pid_buf[pid_str_length] = '\0'; | 1206 WriteLog(err, sizeof(err) - 1); |
1181 | 1207 // Continue anyway, as crash_report may succeed even if we can't read its |
1182 char uid_buf[kUint64StringSize]; | 1208 // status. |
1183 uid_t uid = geteuid(); | 1209 } |
1184 uint64_t uid_str_length = my_uint64_len(uid); | |
1185 my_uint64tos(uid_buf, uid, uid_str_length); | |
1186 uid_buf[uid_str_length] = '\0'; | |
1187 | 1210 |
1188 const char kChromeFlag[] = "--chrome="; | 1211 const char kChromeFlag[] = "--chrome="; |
1189 size_t buf_len = my_strlen(dumpfile) + sizeof(kChromeFlag); | 1212 size_t buf_len = my_strlen(dumpfile) + sizeof(kChromeFlag); |
1190 char* chrome_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); | 1213 char* chrome_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); |
1191 chrome_flag[0] = '\0'; | 1214 chrome_flag[0] = '\0'; |
1192 my_strlcat(chrome_flag, kChromeFlag, buf_len); | 1215 my_strlcat(chrome_flag, kChromeFlag, buf_len); |
1193 my_strlcat(chrome_flag, dumpfile, buf_len); | 1216 my_strlcat(chrome_flag, dumpfile, buf_len); |
1194 | 1217 |
1195 const char kPidFlag[] = "--pid="; | 1218 char* pid_flag = StringFromPrefixAndUint("--pid=", info.pid, allocator); |
1196 buf_len = my_strlen(pid_buf) + sizeof(kPidFlag); | 1219 char* uid_flag = StringFromPrefixAndUint("--uid=", geteuid(), allocator); |
1197 char* pid_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); | |
1198 pid_flag[0] = '\0'; | |
1199 my_strlcat(pid_flag, kPidFlag, buf_len); | |
1200 my_strlcat(pid_flag, pid_buf, buf_len); | |
1201 | |
1202 const char kUidFlag[] = "--uid="; | |
1203 buf_len = my_strlen(uid_buf) + sizeof(kUidFlag); | |
1204 char* uid_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); | |
1205 uid_flag[0] = '\0'; | |
1206 my_strlcat(uid_flag, kUidFlag, buf_len); | |
1207 my_strlcat(uid_flag, uid_buf, buf_len); | |
1208 | 1220 |
1209 const char kExeBuf[] = "--exe="; | 1221 const char kExeBuf[] = "--exe="; |
1210 buf_len = my_strlen(exe_buf) + sizeof(kExeBuf); | 1222 buf_len = my_strlen(exe_buf) + sizeof(kExeBuf); |
1211 char* exe_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); | 1223 char* exe_flag = reinterpret_cast<char*>(allocator->Alloc(buf_len)); |
1212 exe_flag[0] = '\0'; | 1224 exe_flag[0] = '\0'; |
1213 my_strlcat(exe_flag, kExeBuf, buf_len); | 1225 my_strlcat(exe_flag, kExeBuf, buf_len); |
1214 my_strlcat(exe_flag, exe_buf, buf_len); | 1226 my_strlcat(exe_flag, exe_buf, buf_len); |
1215 | 1227 |
1216 const char* args[] = { | 1228 const char* args[] = { |
1217 kCrashReporterBinary, | 1229 kCrashReporterBinary, |
1218 chrome_flag, | 1230 chrome_flag, |
1219 pid_flag, | 1231 pid_flag, |
1220 uid_flag, | 1232 uid_flag, |
1221 exe_flag, | 1233 exe_flag, |
1222 nullptr, | 1234 nullptr, |
1223 }; | 1235 }; |
1224 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1236 static const char msg[] = "Cannot upload crash dump: cannot exec " |
1225 "/sbin/crash_reporter\n"; | 1237 "/sbin/crash_reporter\n"; |
1226 #else | 1238 |
| 1239 #else // defined(OS_CHROMEOS) |
| 1240 |
1227 // Compress |dumpfile| with gzip. | 1241 // Compress |dumpfile| with gzip. |
1228 const pid_t gzip_child = sys_fork(); | 1242 const pid_t gzip_child = sys_fork(); |
1229 if (gzip_child < 0) { | 1243 if (gzip_child < 0) { |
1230 static const char msg[] = "sys_fork() for gzip process failed.\n"; | 1244 static const char msg[] = "sys_fork() for gzip process failed.\n"; |
1231 WriteLog(msg, sizeof(msg) - 1); | 1245 WriteLog(msg, sizeof(msg) - 1); |
1232 sys__exit(1); | 1246 sys__exit(1); |
1233 } | 1247 } |
1234 if (!gzip_child) { | 1248 if (!gzip_child) { |
1235 // gzip process. | 1249 // gzip process. |
1236 const char* args[] = { | 1250 const char* args[] = { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 // The --post-file argument to wget looks like: | 1300 // The --post-file argument to wget looks like: |
1287 // --post-file=/tmp/... | 1301 // --post-file=/tmp/... |
1288 static const char post_file_msg[] = "--post-file="; | 1302 static const char post_file_msg[] = "--post-file="; |
1289 const size_t post_file_size = | 1303 const size_t post_file_size = |
1290 sizeof(post_file_msg) - 1 + my_strlen(dumpfile) + 1; | 1304 sizeof(post_file_msg) - 1 + my_strlen(dumpfile) + 1; |
1291 char* const post_file = reinterpret_cast<char*>(allocator->Alloc( | 1305 char* const post_file = reinterpret_cast<char*>(allocator->Alloc( |
1292 post_file_size)); | 1306 post_file_size)); |
1293 my_strlcpy(post_file, post_file_msg, post_file_size); | 1307 my_strlcpy(post_file, post_file_msg, post_file_size); |
1294 my_strlcat(post_file, dumpfile, post_file_size); | 1308 my_strlcat(post_file, dumpfile, post_file_size); |
1295 | 1309 |
| 1310 // Write the wget status output to the status pipe file descriptor path. |
| 1311 char* status_fd_path = |
| 1312 StringFromPrefixAndUint("/dev/fd/", upload_status_fd, allocator); |
| 1313 |
1296 static const char kWgetBinary[] = "/usr/bin/wget"; | 1314 static const char kWgetBinary[] = "/usr/bin/wget"; |
1297 const char* args[] = { | 1315 const char* args[] = { |
1298 kWgetBinary, | 1316 kWgetBinary, |
1299 header_content_encoding, | 1317 header_content_encoding, |
1300 header_content_type, | 1318 header_content_type, |
1301 post_file, | 1319 post_file, |
1302 kUploadURL, | 1320 kUploadURL, |
1303 "--timeout=10", // Set a timeout so we don't hang forever. | 1321 "--timeout=10", // Set a timeout so we don't hang forever. |
1304 "--tries=1", // Don't retry if the upload fails. | 1322 "--tries=1", // Don't retry if the upload fails. |
1305 "-O", // output reply to fd 3 | 1323 "-O", // Output reply to the file descriptor path. |
1306 "/dev/fd/3", | 1324 status_fd_path, |
1307 nullptr, | 1325 nullptr, |
1308 }; | 1326 }; |
1309 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1327 static const char msg[] = "Cannot upload crash dump: cannot exec " |
1310 "/usr/bin/wget\n"; | 1328 "/usr/bin/wget\n"; |
1311 #endif | 1329 #endif // defined(OS_CHROMEOS) |
| 1330 |
1312 execve(args[0], const_cast<char**>(args), environ); | 1331 execve(args[0], const_cast<char**>(args), environ); |
1313 WriteLog(msg, sizeof(msg) - 1); | 1332 WriteLog(msg, sizeof(msg) - 1); |
1314 sys__exit(1); | 1333 sys__exit(1); |
1315 } | 1334 } |
1316 | 1335 |
1317 // Runs in the helper process to wait for the upload process running | 1336 // Runs in the helper process to wait for the upload process running |
1318 // ExecUploadProcessOrTerminate() to finish. Returns the number of bytes written | 1337 // ExecUploadProcessOrTerminate() to finish. Returns the number of bytes written |
1319 // to |fd| and save the written contents to |buf|. | 1338 // to |fd| and save the written contents to |buf|. |
1320 // |buf| needs to be big enough to hold |bytes_to_read| + 1 characters. | 1339 // |buf| needs to be big enough to hold |bytes_to_read| + 1 characters. |
1321 size_t WaitForCrashReportUploadProcess(int fd, size_t bytes_to_read, | 1340 size_t WaitForCrashReportUploadProcess(int fd, size_t bytes_to_read, |
(...skipping 23 matching lines...) Expand all Loading... |
1345 // |ret| == 0 -> timed out, continue waiting. | 1364 // |ret| == 0 -> timed out, continue waiting. |
1346 // or |bytes_read| < |bytes_to_read| still, keep reading. | 1365 // or |bytes_read| < |bytes_to_read| still, keep reading. |
1347 } | 1366 } |
1348 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. | 1367 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. |
1349 return bytes_read; | 1368 return bytes_read; |
1350 } | 1369 } |
1351 | 1370 |
1352 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. | 1371 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
1353 bool IsValidCrashReportId(const char* buf, size_t bytes_read, | 1372 bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
1354 size_t expected_len) { | 1373 size_t expected_len) { |
1355 if (bytes_read != expected_len) | 1374 if (bytes_read != expected_len) { |
| 1375 static const char msg[] = "Unexpected crash report id length\n"; |
| 1376 WriteLog(msg, sizeof(msg) - 1); |
1356 return false; | 1377 return false; |
| 1378 } |
1357 #if defined(OS_CHROMEOS) | 1379 #if defined(OS_CHROMEOS) |
| 1380 // See kSuccessMagic in platform2/crash-reporter/chrome_collector.cc. |
1358 return my_strcmp(buf, "_sys_cr_finished") == 0; | 1381 return my_strcmp(buf, "_sys_cr_finished") == 0; |
1359 #else | 1382 #else |
1360 for (size_t i = 0; i < bytes_read; ++i) { | 1383 for (size_t i = 0; i < bytes_read; ++i) { |
1361 if (!my_isxdigit(buf[i])) | 1384 if (!my_isxdigit(buf[i])) |
1362 return false; | 1385 return false; |
1363 } | 1386 } |
1364 return true; | 1387 return true; |
1365 #endif | 1388 #endif |
1366 } | 1389 } |
1367 | 1390 |
1368 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. | 1391 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
1369 void HandleCrashReportId(const char* buf, size_t bytes_read, | 1392 void HandleCrashReportId(const char* buf, size_t bytes_read, |
1370 size_t expected_len) { | 1393 size_t expected_len) { |
1371 WriteNewline(); | 1394 WriteNewline(); |
1372 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { | 1395 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { |
1373 #if defined(OS_CHROMEOS) | 1396 #if defined(OS_CHROMEOS) |
1374 static const char msg[] = | 1397 static const char msg[] = |
1375 "System crash-reporter failed to process crash report."; | 1398 "System crash_reporter failed to process crash report."; |
1376 #else | 1399 #else |
1377 static const char msg[] = "Failed to get crash dump id."; | 1400 static const char msg[] = "Failed to get crash dump id."; |
1378 #endif | 1401 #endif |
1379 WriteLog(msg, sizeof(msg) - 1); | 1402 WriteLog(msg, sizeof(msg) - 1); |
1380 WriteNewline(); | 1403 WriteNewline(); |
1381 | 1404 |
1382 static const char id_msg[] = "Report Id: "; | 1405 static const char id_msg[] = "Report Id: "; |
1383 WriteLog(id_msg, sizeof(id_msg) - 1); | 1406 WriteLog(id_msg, sizeof(id_msg) - 1); |
1384 WriteLog(buf, bytes_read); | 1407 WriteLog(buf, bytes_read); |
1385 WriteNewline(); | 1408 WriteNewline(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 if (name) | 1463 if (name) |
1441 return name + 1; | 1464 return name + 1; |
1442 return link; | 1465 return link; |
1443 } | 1466 } |
1444 } | 1467 } |
1445 // Either way too long, or a read error. | 1468 // Either way too long, or a read error. |
1446 return "chrome-crash-unknown-process"; | 1469 return "chrome-crash-unknown-process"; |
1447 } | 1470 } |
1448 #endif | 1471 #endif |
1449 | 1472 |
| 1473 // Attempts to close all open file descriptors other than stdin, stdout and |
| 1474 // stderr (0, 1, and 2). |
| 1475 void CloseAllFileDescriptors() { |
| 1476 const int fd = sys_open("/proc/self/fd", O_DIRECTORY | O_RDONLY, 0); |
| 1477 if (fd < 0) { |
| 1478 for (unsigned i = 3; i < 8192; ++i) |
| 1479 IGNORE_RET(sys_close(i)); |
| 1480 } else { |
| 1481 google_breakpad::DirectoryReader reader(fd); |
| 1482 const char* name; |
| 1483 while (reader.GetNextEntry(&name)) { |
| 1484 int i; |
| 1485 if (my_strtoui(&i, name) && i > 2 && i != fd) |
| 1486 IGNORE_RET(sys_close(i)); |
| 1487 reader.PopEntry(); |
| 1488 } |
| 1489 |
| 1490 IGNORE_RET(sys_close(fd)); |
| 1491 } |
| 1492 } |
| 1493 |
1450 void HandleCrashDump(const BreakpadInfo& info) { | 1494 void HandleCrashDump(const BreakpadInfo& info) { |
1451 int dumpfd; | 1495 int dumpfd; |
1452 bool keep_fd = false; | 1496 bool keep_fd = false; |
1453 size_t dump_size; | 1497 size_t dump_size; |
1454 uint8_t* dump_data; | 1498 uint8_t* dump_data; |
1455 google_breakpad::PageAllocator allocator; | 1499 google_breakpad::PageAllocator allocator; |
1456 const char* exe_buf = nullptr; | 1500 const char* exe_buf = nullptr; |
1457 | 1501 |
1458 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { | 1502 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { |
1459 return; | 1503 return; |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 // | 1816 // |
1773 // This code is called both when a browser is crashing (in which case, | 1817 // 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 | 1818 // nothing really matters any more) and when a renderer/plugin crashes, in |
1775 // which case we need to continue. | 1819 // which case we need to continue. |
1776 // | 1820 // |
1777 // Since we are a multithreaded app, if we were just to fork(), we might | 1821 // 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 | 1822 // grab file descriptors which have just been created in another thread and |
1779 // hold them open for too long. | 1823 // hold them open for too long. |
1780 // | 1824 // |
1781 // Thus, we have to loop and try and close everything. | 1825 // Thus, we have to loop and try and close everything. |
1782 const int fd = sys_open("/proc/self/fd", O_DIRECTORY | O_RDONLY, 0); | 1826 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 | 1827 |
1799 IGNORE_RET(sys_setsid()); | 1828 IGNORE_RET(sys_setsid()); |
1800 | 1829 |
1801 // Leave one end of a pipe in the upload process and watch for it getting | 1830 // Leave one end of a pipe in the upload process and watch for it getting |
1802 // closed by the upload process exiting. | 1831 // closed by the upload process exiting. |
1803 int fds[2]; | 1832 int fds[2]; |
1804 if (sys_pipe(fds) >= 0) { | 1833 if (sys_pipe(fds) >= 0) { |
1805 const pid_t upload_child = sys_fork(); | 1834 const pid_t upload_child = sys_fork(); |
1806 if (!upload_child) { | 1835 if (!upload_child) { |
1807 // Upload process. | 1836 // Upload process. |
1808 IGNORE_RET(sys_close(fds[0])); | 1837 IGNORE_RET(sys_close(fds[0])); // Close read end of pipe. |
1809 IGNORE_RET(sys_dup2(fds[1], 3)); | 1838 // Write status to the pipe. |
1810 ExecUploadProcessOrTerminate(info, temp_file, mime_boundary, exe_buf, | 1839 ExecUploadProcessOrTerminate(info, temp_file, mime_boundary, exe_buf, |
1811 &allocator); | 1840 fds[1], &allocator); |
1812 } | 1841 } |
1813 | 1842 |
1814 // Helper process. | 1843 // Helper process. |
1815 if (upload_child > 0) { | 1844 if (upload_child > 0) { |
1816 IGNORE_RET(sys_close(fds[1])); | 1845 IGNORE_RET(sys_close(fds[1])); // Close write end of pipe. |
1817 | 1846 |
1818 const size_t kCrashIdLength = 16; | 1847 const size_t kCrashIdLength = 16; |
1819 char id_buf[kCrashIdLength + 1]; | 1848 char id_buf[kCrashIdLength + 1]; |
1820 size_t bytes_read = | 1849 size_t bytes_read = |
1821 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); | 1850 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); |
1822 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); | 1851 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); |
1823 | 1852 |
1824 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { | 1853 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { |
1825 // Upload process is still around, kill it. | 1854 // Upload process is still around, kill it. |
1826 sys_kill(upload_child, SIGKILL); | 1855 sys_kill(upload_child, SIGKILL); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 void SuppressDumpGeneration() { | 2003 void SuppressDumpGeneration() { |
1975 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; | 2004 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; |
1976 } | 2005 } |
1977 #endif // OS_ANDROID | 2006 #endif // OS_ANDROID |
1978 | 2007 |
1979 bool IsCrashReporterEnabled() { | 2008 bool IsCrashReporterEnabled() { |
1980 return g_is_crash_reporter_enabled; | 2009 return g_is_crash_reporter_enabled; |
1981 } | 2010 } |
1982 | 2011 |
1983 } // namespace breakpad | 2012 } // namespace breakpad |
OLD | NEW |