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/app/breakpad_linux.h" | 8 #include "components/crash/app/breakpad_linux.h" |
9 | 9 |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "base/path_service.h" | 31 #include "base/path_service.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/crash_generation/crash_generation_client.h" | 36 #include "breakpad/src/client/linux/crash_generation/crash_generation_client.h" |
37 #include "breakpad/src/client/linux/handler/exception_handler.h" | 37 #include "breakpad/src/client/linux/handler/exception_handler.h" |
38 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" | 38 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" |
39 #include "breakpad/src/common/linux/linux_libc_support.h" | 39 #include "breakpad/src/common/linux/linux_libc_support.h" |
40 #include "breakpad/src/common/memory.h" | 40 #include "breakpad/src/common/memory.h" |
41 #include "components/crash/app/breakpad_client.h" | |
42 #include "components/crash/app/breakpad_linux_impl.h" | 41 #include "components/crash/app/breakpad_linux_impl.h" |
| 42 #include "components/crash/app/crash_reporter_client.h" |
43 #include "content/public/common/content_descriptors.h" | 43 #include "content/public/common/content_descriptors.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 |
52 #include "third_party/lss/linux_syscall_support.h" | 52 #include "third_party/lss/linux_syscall_support.h" |
53 | 53 |
54 #if defined(ADDRESS_SANITIZER) | 54 #if defined(ADDRESS_SANITIZER) |
55 #include <ucontext.h> // for getcontext(). | 55 #include <ucontext.h> // for getcontext(). |
56 #endif | 56 #endif |
57 | 57 |
58 #if defined(OS_ANDROID) | 58 #if defined(OS_ANDROID) |
59 #define STAT_STRUCT struct stat | 59 #define STAT_STRUCT struct stat |
60 #define FSTAT_FUNC fstat | 60 #define FSTAT_FUNC fstat |
61 #else | 61 #else |
62 #define STAT_STRUCT struct kernel_stat | 62 #define STAT_STRUCT struct kernel_stat |
63 #define FSTAT_FUNC sys_fstat | 63 #define FSTAT_FUNC sys_fstat |
64 #endif | 64 #endif |
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 crash_reporter::GetCrashReporterClient; |
72 using google_breakpad::ExceptionHandler; | 73 using google_breakpad::ExceptionHandler; |
73 using google_breakpad::MinidumpDescriptor; | 74 using google_breakpad::MinidumpDescriptor; |
74 | 75 |
75 namespace breakpad { | 76 namespace breakpad { |
76 | 77 |
77 namespace { | 78 namespace { |
78 | 79 |
79 #if !defined(OS_CHROMEOS) | 80 #if !defined(OS_CHROMEOS) |
80 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 81 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
81 #endif | 82 #endif |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 while (len > 0 && str[len - 1] == ' ') { | 200 while (len > 0 && str[len - 1] == ' ') { |
200 len--; | 201 len--; |
201 } | 202 } |
202 return len; | 203 return len; |
203 } | 204 } |
204 | 205 |
205 void SetClientIdFromCommandLine(const CommandLine& command_line) { | 206 void SetClientIdFromCommandLine(const CommandLine& command_line) { |
206 // Get the guid from the command line switch. | 207 // Get the guid from the command line switch. |
207 std::string switch_value = | 208 std::string switch_value = |
208 command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); | 209 command_line.GetSwitchValueASCII(switches::kEnableCrashReporter); |
209 GetBreakpadClient()->SetBreakpadClientIdFromGUID(switch_value); | 210 GetCrashReporterClient()->SetCrashReporterClientIdFromGUID(switch_value); |
210 } | 211 } |
211 | 212 |
212 // MIME substrings. | 213 // MIME substrings. |
213 #if defined(OS_CHROMEOS) | 214 #if defined(OS_CHROMEOS) |
214 const char g_sep[] = ":"; | 215 const char g_sep[] = ":"; |
215 #endif | 216 #endif |
216 const char g_rn[] = "\r\n"; | 217 const char g_rn[] = "\r\n"; |
217 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 218 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
218 const char g_quote_msg[] = "\""; | 219 const char g_quote_msg[] = "\""; |
219 const char g_dashdash_msg[] = "--"; | 220 const char g_dashdash_msg[] = "--"; |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 } | 624 } |
624 #endif | 625 #endif |
625 | 626 |
626 void EnableCrashDumping(bool unattended) { | 627 void EnableCrashDumping(bool unattended) { |
627 g_is_crash_reporter_enabled = true; | 628 g_is_crash_reporter_enabled = true; |
628 | 629 |
629 base::FilePath tmp_path("/tmp"); | 630 base::FilePath tmp_path("/tmp"); |
630 PathService::Get(base::DIR_TEMP, &tmp_path); | 631 PathService::Get(base::DIR_TEMP, &tmp_path); |
631 | 632 |
632 base::FilePath dumps_path(tmp_path); | 633 base::FilePath dumps_path(tmp_path); |
633 if (GetBreakpadClient()->GetCrashDumpLocation(&dumps_path)) { | 634 if (GetCrashReporterClient()->GetCrashDumpLocation(&dumps_path)) { |
634 base::FilePath logfile = | 635 base::FilePath logfile = |
635 dumps_path.Append(GetBreakpadClient()->GetReporterLogFilename()); | 636 dumps_path.Append(GetCrashReporterClient()->GetReporterLogFilename()); |
636 std::string logfile_str = logfile.value(); | 637 std::string logfile_str = logfile.value(); |
637 const size_t crash_log_path_len = logfile_str.size() + 1; | 638 const size_t crash_log_path_len = logfile_str.size() + 1; |
638 g_crash_log_path = new char[crash_log_path_len]; | 639 g_crash_log_path = new char[crash_log_path_len]; |
639 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); | 640 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); |
640 } | 641 } |
641 DCHECK(!g_breakpad); | 642 DCHECK(!g_breakpad); |
642 MinidumpDescriptor minidump_descriptor(dumps_path.value()); | 643 MinidumpDescriptor minidump_descriptor(dumps_path.value()); |
643 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); | 644 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); |
644 #if defined(OS_ANDROID) | 645 #if defined(OS_ANDROID) |
645 unattended = true; // Android never uploads directly. | 646 unattended = true; // Android never uploads directly. |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 | 861 |
861 void SetCrashKeyValue(const base::StringPiece& key, | 862 void SetCrashKeyValue(const base::StringPiece& key, |
862 const base::StringPiece& value) { | 863 const base::StringPiece& value) { |
863 g_crash_keys->SetKeyValue(key.data(), value.data()); | 864 g_crash_keys->SetKeyValue(key.data(), value.data()); |
864 } | 865 } |
865 | 866 |
866 void ClearCrashKey(const base::StringPiece& key) { | 867 void ClearCrashKey(const base::StringPiece& key) { |
867 g_crash_keys->RemoveKey(key.data()); | 868 g_crash_keys->RemoveKey(key.data()); |
868 } | 869 } |
869 | 870 |
870 // GetBreakpadClient() cannot call any Set methods until after InitCrashKeys(). | 871 // GetCrashReporterClient() cannot call any Set methods until after |
| 872 // InitCrashKeys(). |
871 void InitCrashKeys() { | 873 void InitCrashKeys() { |
872 g_crash_keys = new CrashKeyStorage; | 874 g_crash_keys = new CrashKeyStorage; |
873 GetBreakpadClient()->RegisterCrashKeys(); | 875 GetCrashReporterClient()->RegisterCrashKeys(); |
874 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValue, &ClearCrashKey); | 876 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValue, &ClearCrashKey); |
875 } | 877 } |
876 | 878 |
877 // Miscellaneous initialization functions to call after Breakpad has been | 879 // Miscellaneous initialization functions to call after Breakpad has been |
878 // enabled. | 880 // enabled. |
879 void PostEnableBreakpadInitialization() { | 881 void PostEnableBreakpadInitialization() { |
880 SetProcessStartTime(); | 882 SetProcessStartTime(); |
881 g_pid = getpid(); | 883 g_pid = getpid(); |
882 | 884 |
883 base::debug::SetDumpWithoutCrashingFunction(&DumpProcess); | 885 base::debug::SetDumpWithoutCrashingFunction(&DumpProcess); |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 #if defined(OS_CHROMEOS) | 1304 #if defined(OS_CHROMEOS) |
1303 CrashReporterWriter writer(temp_file_fd); | 1305 CrashReporterWriter writer(temp_file_fd); |
1304 #else | 1306 #else |
1305 MimeWriter writer(temp_file_fd, mime_boundary); | 1307 MimeWriter writer(temp_file_fd, mime_boundary); |
1306 #endif | 1308 #endif |
1307 { | 1309 { |
1308 // TODO(thestig) Do not use this inside a compromised context. | 1310 // TODO(thestig) Do not use this inside a compromised context. |
1309 std::string product_name; | 1311 std::string product_name; |
1310 std::string version; | 1312 std::string version; |
1311 | 1313 |
1312 GetBreakpadClient()->GetProductNameAndVersion(&product_name, &version); | 1314 GetCrashReporterClient()->GetProductNameAndVersion(&product_name, &version); |
1313 | 1315 |
1314 writer.AddBoundary(); | 1316 writer.AddBoundary(); |
1315 writer.AddPairString("prod", product_name.c_str()); | 1317 writer.AddPairString("prod", product_name.c_str()); |
1316 writer.AddBoundary(); | 1318 writer.AddBoundary(); |
1317 writer.AddPairString("ver", version.c_str()); | 1319 writer.AddPairString("ver", version.c_str()); |
1318 writer.AddBoundary(); | 1320 writer.AddBoundary(); |
1319 if (info.pid > 0) { | 1321 if (info.pid > 0) { |
1320 char pid_value_buf[kUint64StringSize]; | 1322 char pid_value_buf[kUint64StringSize]; |
1321 uint64_t pid_value_len = my_uint64_len(info.pid); | 1323 uint64_t pid_value_len = my_uint64_len(info.pid); |
1322 my_uint64tos(pid_value_buf, info.pid, pid_value_len); | 1324 my_uint64tos(pid_value_buf, info.pid, pid_value_len); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 // This will guarantee that the BuildInfo has been initialized and subsequent | 1547 // This will guarantee that the BuildInfo has been initialized and subsequent |
1546 // calls will not require memory allocation. | 1548 // calls will not require memory allocation. |
1547 base::android::BuildInfo::GetInstance(); | 1549 base::android::BuildInfo::GetInstance(); |
1548 #endif | 1550 #endif |
1549 // Determine the process type and take appropriate action. | 1551 // Determine the process type and take appropriate action. |
1550 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 1552 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
1551 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) | 1553 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) |
1552 return; | 1554 return; |
1553 | 1555 |
1554 if (process_type.empty()) { | 1556 if (process_type.empty()) { |
1555 bool enable_breakpad = GetBreakpadClient()->GetCollectStatsConsent() || | 1557 bool enable_breakpad = GetCrashReporterClient()->GetCollectStatsConsent() || |
1556 GetBreakpadClient()->IsRunningUnattended(); | 1558 GetCrashReporterClient()->IsRunningUnattended(); |
1557 enable_breakpad &= | 1559 enable_breakpad &= |
1558 !parsed_command_line.HasSwitch(switches::kDisableBreakpad); | 1560 !parsed_command_line.HasSwitch(switches::kDisableBreakpad); |
1559 if (!enable_breakpad) { | 1561 if (!enable_breakpad) { |
1560 enable_breakpad = parsed_command_line.HasSwitch( | 1562 enable_breakpad = parsed_command_line.HasSwitch( |
1561 switches::kEnableCrashReporterForTesting); | 1563 switches::kEnableCrashReporterForTesting); |
1562 } | 1564 } |
1563 if (!enable_breakpad) { | 1565 if (!enable_breakpad) { |
1564 VLOG(1) << "Breakpad disabled"; | 1566 VLOG(1) << "Breakpad disabled"; |
1565 return; | 1567 return; |
1566 } | 1568 } |
1567 | 1569 |
1568 InitCrashKeys(); | 1570 InitCrashKeys(); |
1569 EnableCrashDumping(GetBreakpadClient()->IsRunningUnattended()); | 1571 EnableCrashDumping(GetCrashReporterClient()->IsRunningUnattended()); |
1570 } else if (GetBreakpadClient()->EnableBreakpadForProcess(process_type)) { | 1572 } else if (GetCrashReporterClient()->EnableBreakpadForProcess(process_type)) { |
1571 #if defined(OS_ANDROID) | 1573 #if defined(OS_ANDROID) |
1572 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " | 1574 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " |
1573 "InitNonBrowserCrashReporter in " << process_type << " process."; | 1575 "InitNonBrowserCrashReporter in " << process_type << " process."; |
1574 return; | 1576 return; |
1575 #else | 1577 #else |
1576 // We might be chrooted in a zygote or renderer process so we cannot call | 1578 // We might be chrooted in a zygote or renderer process so we cannot call |
1577 // GetCollectStatsConsent because that needs access the the user's home | 1579 // GetCollectStatsConsent because that needs access the the user's home |
1578 // dir. Instead, we set a command line flag for these processes. | 1580 // dir. Instead, we set a command line flag for these processes. |
1579 // Even though plugins are not chrooted, we share the same code path for | 1581 // Even though plugins are not chrooted, we share the same code path for |
1580 // simplicity. | 1582 // simplicity. |
(...skipping 10 matching lines...) Expand all Loading... |
1591 } | 1593 } |
1592 | 1594 |
1593 #if defined(OS_ANDROID) | 1595 #if defined(OS_ANDROID) |
1594 void InitNonBrowserCrashReporterForAndroid(const std::string& process_type) { | 1596 void InitNonBrowserCrashReporterForAndroid(const std::string& process_type) { |
1595 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1597 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
1596 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { | 1598 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { |
1597 // On Android we need to provide a FD to the file where the minidump is | 1599 // On Android we need to provide a FD to the file where the minidump is |
1598 // generated as the renderer and browser run with different UIDs | 1600 // generated as the renderer and browser run with different UIDs |
1599 // (preventing the browser from inspecting the renderer process). | 1601 // (preventing the browser from inspecting the renderer process). |
1600 int minidump_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( | 1602 int minidump_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( |
1601 GetBreakpadClient()->GetAndroidMinidumpDescriptor()); | 1603 GetCrashReporterClient()->GetAndroidMinidumpDescriptor()); |
1602 if (minidump_fd < 0) { | 1604 if (minidump_fd < 0) { |
1603 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; | 1605 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; |
1604 } else { | 1606 } else { |
1605 EnableNonBrowserCrashDumping(process_type, minidump_fd); | 1607 EnableNonBrowserCrashDumping(process_type, minidump_fd); |
1606 } | 1608 } |
1607 } | 1609 } |
1608 } | 1610 } |
1609 #endif // OS_ANDROID | 1611 #endif // OS_ANDROID |
1610 | 1612 |
1611 bool IsCrashReporterEnabled() { | 1613 bool IsCrashReporterEnabled() { |
1612 return g_is_crash_reporter_enabled; | 1614 return g_is_crash_reporter_enabled; |
1613 } | 1615 } |
1614 | 1616 |
1615 } // namespace breakpad | 1617 } // namespace breakpad |
OLD | NEW |