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 | 7 |
8 #include "chrome/app/breakpad_linux.h" | 8 #include "components/breakpad/app/breakpad_linux.h" |
9 | 9 |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
11 #include <poll.h> | 11 #include <poll.h> |
12 #include <signal.h> | 12 #include <signal.h> |
13 #include <stdlib.h> | 13 #include <stdlib.h> |
14 #include <sys/socket.h> | 14 #include <sys/socket.h> |
15 #include <sys/time.h> | 15 #include <sys/time.h> |
16 #include <sys/types.h> | 16 #include <sys/types.h> |
17 #include <sys/uio.h> | 17 #include <sys/uio.h> |
18 #include <sys/wait.h> | 18 #include <sys/wait.h> |
(...skipping 11 matching lines...) Expand all Loading... |
30 #include "base/path_service.h" | 30 #include "base/path_service.h" |
31 #include "base/platform_file.h" | 31 #include "base/platform_file.h" |
32 #include "base/posix/eintr_wrapper.h" | 32 #include "base/posix/eintr_wrapper.h" |
33 #include "base/posix/global_descriptors.h" | 33 #include "base/posix/global_descriptors.h" |
34 #include "base/process/memory.h" | 34 #include "base/process/memory.h" |
35 #include "base/strings/string_util.h" | 35 #include "base/strings/string_util.h" |
36 #include "breakpad/src/client/linux/handler/exception_handler.h" | 36 #include "breakpad/src/client/linux/handler/exception_handler.h" |
37 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" | 37 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" |
38 #include "breakpad/src/common/linux/linux_libc_support.h" | 38 #include "breakpad/src/common/linux/linux_libc_support.h" |
39 #include "breakpad/src/common/memory.h" | 39 #include "breakpad/src/common/memory.h" |
40 #include "chrome/app/breakpad_linux_impl.h" | 40 #include "components/breakpad/app/breakpad_client.h" |
41 #include "components/breakpad/breakpad_client.h" | 41 #include "components/breakpad/app/breakpad_linux_impl.h" |
42 #include "content/public/common/content_descriptors.h" | 42 #include "content/public/common/content_descriptors.h" |
43 #include "content/public/common/content_switches.h" | 43 #include "content/public/common/content_switches.h" |
44 | 44 |
45 #if defined(OS_ANDROID) | 45 #if defined(OS_ANDROID) |
46 #include <android/log.h> | 46 #include <android/log.h> |
47 #include <sys/stat.h> | 47 #include <sys/stat.h> |
48 | 48 |
49 #include "base/android/build_info.h" | 49 #include "base/android/build_info.h" |
50 #include "base/android/path_utils.h" | 50 #include "base/android/path_utils.h" |
51 #endif | 51 #endif |
(...skipping 13 matching lines...) Expand all Loading... |
65 | 65 |
66 // Some versions of gcc are prone to warn about unused return values. In cases | 66 // Some versions of gcc are prone to warn about unused return values. In cases |
67 // where we either a) know the call cannot fail, or b) there is nothing we | 67 // where we either a) know the call cannot fail, or b) there is nothing we |
68 // can do when a call fails, we mark the return code as ignored. This avoids | 68 // can do when a call fails, we mark the return code as ignored. This avoids |
69 // spurious compiler warnings. | 69 // spurious compiler warnings. |
70 #define IGNORE_RET(x) do { if (x); } while (0) | 70 #define IGNORE_RET(x) do { if (x); } while (0) |
71 | 71 |
72 using google_breakpad::ExceptionHandler; | 72 using google_breakpad::ExceptionHandler; |
73 using google_breakpad::MinidumpDescriptor; | 73 using google_breakpad::MinidumpDescriptor; |
74 | 74 |
| 75 namespace breakpad { |
| 76 |
75 namespace { | 77 namespace { |
76 | 78 |
77 #if !defined(OS_CHROMEOS) | 79 #if !defined(OS_CHROMEOS) |
78 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 80 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
79 #endif | 81 #endif |
80 | 82 |
81 bool g_is_crash_reporter_enabled = false; | 83 bool g_is_crash_reporter_enabled = false; |
82 uint64_t g_process_start_time = 0; | 84 uint64_t g_process_start_time = 0; |
83 char* g_crash_log_path = NULL; | 85 char* g_crash_log_path = NULL; |
84 ExceptionHandler* g_breakpad = NULL; | 86 ExceptionHandler* g_breakpad = NULL; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 if (distro_len_param) | 204 if (distro_len_param) |
203 *distro_len_param = distro_len; | 205 *distro_len_param = distro_len; |
204 } | 206 } |
205 | 207 |
206 void SetClientIdFromCommandLine(const CommandLine& command_line) { | 208 void SetClientIdFromCommandLine(const CommandLine& command_line) { |
207 // Get the guid and linux distro from the command line switch. | 209 // Get the guid and linux distro from the command line switch. |
208 std::string switch_value = | 210 std::string switch_value = |
209 command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); | 211 command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); |
210 size_t separator = switch_value.find(","); | 212 size_t separator = switch_value.find(","); |
211 if (separator != std::string::npos) { | 213 if (separator != std::string::npos) { |
212 breakpad::GetBreakpadClient()->SetClientID( | 214 GetBreakpadClient()->SetClientID(switch_value.substr(0, separator)); |
213 switch_value.substr(0, separator)); | |
214 base::SetLinuxDistro(switch_value.substr(separator + 1)); | 215 base::SetLinuxDistro(switch_value.substr(separator + 1)); |
215 } else { | 216 } else { |
216 breakpad::GetBreakpadClient()->SetClientID(switch_value); | 217 GetBreakpadClient()->SetClientID(switch_value); |
217 } | 218 } |
218 } | 219 } |
219 | 220 |
220 // MIME substrings. | 221 // MIME substrings. |
221 #if defined(OS_CHROMEOS) | 222 #if defined(OS_CHROMEOS) |
222 const char g_sep[] = ":"; | 223 const char g_sep[] = ":"; |
223 #endif | 224 #endif |
224 const char g_rn[] = "\r\n"; | 225 const char g_rn[] = "\r\n"; |
225 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 226 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
226 const char g_quote_msg[] = "\""; | 227 const char g_quote_msg[] = "\""; |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 628 } |
628 #endif | 629 #endif |
629 | 630 |
630 void EnableCrashDumping(bool unattended) { | 631 void EnableCrashDumping(bool unattended) { |
631 g_is_crash_reporter_enabled = true; | 632 g_is_crash_reporter_enabled = true; |
632 | 633 |
633 base::FilePath tmp_path("/tmp"); | 634 base::FilePath tmp_path("/tmp"); |
634 PathService::Get(base::DIR_TEMP, &tmp_path); | 635 PathService::Get(base::DIR_TEMP, &tmp_path); |
635 | 636 |
636 base::FilePath dumps_path(tmp_path); | 637 base::FilePath dumps_path(tmp_path); |
637 if (breakpad::GetBreakpadClient()->GetCrashDumpLocation(&dumps_path)) { | 638 if (GetBreakpadClient()->GetCrashDumpLocation(&dumps_path)) { |
638 base::FilePath logfile = dumps_path.Append( | 639 base::FilePath logfile = |
639 breakpad::GetBreakpadClient()->GetReporterLogFilename()); | 640 dumps_path.Append(GetBreakpadClient()->GetReporterLogFilename()); |
640 std::string logfile_str = logfile.value(); | 641 std::string logfile_str = logfile.value(); |
641 const size_t crash_log_path_len = logfile_str.size() + 1; | 642 const size_t crash_log_path_len = logfile_str.size() + 1; |
642 g_crash_log_path = new char[crash_log_path_len]; | 643 g_crash_log_path = new char[crash_log_path_len]; |
643 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); | 644 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); |
644 } | 645 } |
645 DCHECK(!g_breakpad); | 646 DCHECK(!g_breakpad); |
646 MinidumpDescriptor minidump_descriptor(dumps_path.value()); | 647 MinidumpDescriptor minidump_descriptor(dumps_path.value()); |
647 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); | 648 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); |
648 #if defined(OS_ANDROID) | 649 #if defined(OS_ANDROID) |
649 unattended = true; // Android never uploads directly. | 650 unattended = true; // Android never uploads directly. |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 | 1160 |
1160 #if defined(OS_CHROMEOS) | 1161 #if defined(OS_CHROMEOS) |
1161 CrashReporterWriter writer(temp_file_fd); | 1162 CrashReporterWriter writer(temp_file_fd); |
1162 #else | 1163 #else |
1163 MimeWriter writer(temp_file_fd, mime_boundary); | 1164 MimeWriter writer(temp_file_fd, mime_boundary); |
1164 #endif | 1165 #endif |
1165 { | 1166 { |
1166 std::string product_name; | 1167 std::string product_name; |
1167 std::string version; | 1168 std::string version; |
1168 | 1169 |
1169 breakpad::GetBreakpadClient()->GetProductNameAndVersion(&product_name, | 1170 GetBreakpadClient()->GetProductNameAndVersion(&product_name, &version); |
1170 &version); | |
1171 | 1171 |
1172 writer.AddBoundary(); | 1172 writer.AddBoundary(); |
1173 writer.AddPairString("prod", product_name.c_str()); | 1173 writer.AddPairString("prod", product_name.c_str()); |
1174 writer.AddBoundary(); | 1174 writer.AddBoundary(); |
1175 writer.AddPairString("ver", version.c_str()); | 1175 writer.AddPairString("ver", version.c_str()); |
1176 writer.AddBoundary(); | 1176 writer.AddBoundary(); |
1177 if (info.pid > 0) { | 1177 if (info.pid > 0) { |
1178 char pid_value_buf[kUint64StringSize]; | 1178 char pid_value_buf[kUint64StringSize]; |
1179 uint64_t pid_value_len = my_uint64_len(info.pid); | 1179 uint64_t pid_value_len = my_uint64_len(info.pid); |
1180 my_uint64tos(pid_value_buf, info.pid, pid_value_len); | 1180 my_uint64tos(pid_value_buf, info.pid, pid_value_len); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 base::android::BuildInfo::GetInstance(); | 1445 base::android::BuildInfo::GetInstance(); |
1446 #endif | 1446 #endif |
1447 // Determine the process type and take appropriate action. | 1447 // Determine the process type and take appropriate action. |
1448 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 1448 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
1449 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) | 1449 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) |
1450 return; | 1450 return; |
1451 | 1451 |
1452 const std::string process_type = | 1452 const std::string process_type = |
1453 parsed_command_line.GetSwitchValueASCII(switches::kProcessType); | 1453 parsed_command_line.GetSwitchValueASCII(switches::kProcessType); |
1454 if (process_type.empty()) { | 1454 if (process_type.empty()) { |
1455 EnableCrashDumping(breakpad::GetBreakpadClient()->IsRunningUnattended()); | 1455 EnableCrashDumping(GetBreakpadClient()->IsRunningUnattended()); |
1456 } else if (process_type == switches::kRendererProcess || | 1456 } else if (process_type == switches::kRendererProcess || |
1457 process_type == switches::kPluginProcess || | 1457 process_type == switches::kPluginProcess || |
1458 process_type == switches::kPpapiPluginProcess || | 1458 process_type == switches::kPpapiPluginProcess || |
1459 process_type == switches::kZygoteProcess || | 1459 process_type == switches::kZygoteProcess || |
1460 process_type == switches::kGpuProcess) { | 1460 process_type == switches::kGpuProcess) { |
1461 #if defined(OS_ANDROID) | 1461 #if defined(OS_ANDROID) |
1462 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " | 1462 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " |
1463 "InitNonBrowserCrashReporter in " << process_type << " process."; | 1463 "InitNonBrowserCrashReporter in " << process_type << " process."; |
1464 return; | 1464 return; |
1465 #else | 1465 #else |
1466 // We might be chrooted in a zygote or renderer process so we cannot call | 1466 // We might be chrooted in a zygote or renderer process so we cannot call |
1467 // GetCollectStatsConsent because that needs access the the user's home | 1467 // GetCollectStatsConsent because that needs access the the user's home |
1468 // dir. Instead, we set a command line flag for these processes. | 1468 // dir. Instead, we set a command line flag for these processes. |
1469 // Even though plugins are not chrooted, we share the same code path for | 1469 // Even though plugins are not chrooted, we share the same code path for |
1470 // simplicity. | 1470 // simplicity. |
1471 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) | 1471 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) |
1472 return; | 1472 return; |
1473 SetClientIdFromCommandLine(parsed_command_line); | 1473 SetClientIdFromCommandLine(parsed_command_line); |
1474 EnableNonBrowserCrashDumping(); | 1474 EnableNonBrowserCrashDumping(); |
1475 VLOG(1) << "Non Browser crash dumping enabled for: " << process_type; | 1475 VLOG(1) << "Non Browser crash dumping enabled for: " << process_type; |
1476 #endif // #if defined(OS_ANDROID) | 1476 #endif // #if defined(OS_ANDROID) |
1477 } | 1477 } |
1478 | 1478 |
1479 SetProcessStartTime(); | 1479 SetProcessStartTime(); |
1480 | 1480 |
1481 breakpad::GetBreakpadClient()->SetDumpWithoutCrashingFunction(&DumpProcess); | 1481 GetBreakpadClient()->SetDumpWithoutCrashingFunction(&DumpProcess); |
1482 #if defined(ADDRESS_SANITIZER) | 1482 #if defined(ADDRESS_SANITIZER) |
1483 // Register the callback for AddressSanitizer error reporting. | 1483 // Register the callback for AddressSanitizer error reporting. |
1484 __asan_set_error_report_callback(AsanLinuxBreakpadCallback); | 1484 __asan_set_error_report_callback(AsanLinuxBreakpadCallback); |
1485 #endif | 1485 #endif |
1486 | 1486 |
1487 g_crash_keys = new CrashKeyStorage; | 1487 g_crash_keys = new CrashKeyStorage; |
1488 breakpad::GetBreakpadClient()->RegisterCrashKeys(); | 1488 GetBreakpadClient()->RegisterCrashKeys(); |
1489 base::debug::SetCrashKeyReportingFunctions( | 1489 base::debug::SetCrashKeyReportingFunctions( |
1490 &SetCrashKeyValue, &ClearCrashKey); | 1490 &SetCrashKeyValue, &ClearCrashKey); |
1491 } | 1491 } |
1492 | 1492 |
1493 #if defined(OS_ANDROID) | 1493 #if defined(OS_ANDROID) |
1494 void InitNonBrowserCrashReporterForAndroid() { | 1494 void InitNonBrowserCrashReporterForAndroid() { |
1495 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1495 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
1496 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { | 1496 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { |
1497 // On Android we need to provide a FD to the file where the minidump is | 1497 // On Android we need to provide a FD to the file where the minidump is |
1498 // generated as the renderer and browser run with different UIDs | 1498 // generated as the renderer and browser run with different UIDs |
1499 // (preventing the browser from inspecting the renderer process). | 1499 // (preventing the browser from inspecting the renderer process). |
1500 int minidump_fd = base::GlobalDescriptors::GetInstance()-> | 1500 int minidump_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( |
1501 MaybeGet(breakpad::GetBreakpadClient()->GetAndroidMinidumpDescriptor()); | 1501 GetBreakpadClient()->GetAndroidMinidumpDescriptor()); |
1502 if (minidump_fd == base::kInvalidPlatformFileValue) { | 1502 if (minidump_fd == base::kInvalidPlatformFileValue) { |
1503 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; | 1503 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; |
1504 } else { | 1504 } else { |
1505 EnableNonBrowserCrashDumping(minidump_fd); | 1505 EnableNonBrowserCrashDumping(minidump_fd); |
1506 } | 1506 } |
1507 } | 1507 } |
1508 } | 1508 } |
1509 #endif // OS_ANDROID | 1509 #endif // OS_ANDROID |
1510 | 1510 |
1511 bool IsCrashReporterEnabled() { | 1511 bool IsCrashReporterEnabled() { |
1512 return g_is_crash_reporter_enabled; | 1512 return g_is_crash_reporter_enabled; |
1513 } | 1513 } |
| 1514 |
| 1515 } // namespace breakpad |
OLD | NEW |