| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "ios/chrome/browser/crash_report/breakpad_helper.h" | 5 #include "ios/chrome/browser/crash_report/breakpad_helper.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 const base::StringPiece& value) { | 71 const base::StringPiece& value) { |
| 72 AddReportParameter(base::SysUTF8ToNSString(key.as_string()), | 72 AddReportParameter(base::SysUTF8ToNSString(key.as_string()), |
| 73 base::SysUTF8ToNSString(value.as_string()), true); | 73 base::SysUTF8ToNSString(value.as_string()), true); |
| 74 } | 74 } |
| 75 | 75 |
| 76 // Callback for base::debug::SetCrashKeyReportingFunctions | 76 // Callback for base::debug::SetCrashKeyReportingFunctions |
| 77 void ClearCrashKeyValueImpl(const base::StringPiece& key) { | 77 void ClearCrashKeyValueImpl(const base::StringPiece& key) { |
| 78 RemoveReportParameter(base::SysUTF8ToNSString(key.as_string())); | 78 RemoveReportParameter(base::SysUTF8ToNSString(key.as_string())); |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Callback for logging::SetLogMessageHandler | 81 class FatalMessageListener : logging::LogMessageListener { |
| 82 bool FatalMessageHandler(int severity, | 82 void OnMessage(int severity, |
| 83 const char* file, | 83 const char* file, |
| 84 int line, | 84 int line, |
| 85 size_t message_start, | 85 size_t message_start, |
| 86 const std::string& str) { | 86 const std::string& str) override; |
| 87 }; |
| 88 |
| 89 void FatalMessageListener::OnMessage(int severity, |
| 90 const char* file, |
| 91 int line, |
| 92 size_t message_start, |
| 93 const std::string& str) { |
| 87 // Do not handle non-FATAL. | 94 // Do not handle non-FATAL. |
| 88 if (severity != logging::LOG_FATAL) | 95 if (severity != logging::LOG_FATAL) |
| 89 return false; | 96 return; |
| 90 | 97 |
| 91 // In case of OOM condition, this code could be reentered when | 98 // In case of OOM condition, this code could be reentered when |
| 92 // constructing and storing the key. Using a static is not | 99 // constructing and storing the key. Using a static is not |
| 93 // thread-safe, but if multiple threads are in the process of a | 100 // thread-safe, but if multiple threads are in the process of a |
| 94 // fatal crash at the same time, this should work. | 101 // fatal crash at the same time, this should work. |
| 95 static bool guarded = false; | 102 static bool guarded = false; |
| 96 if (guarded) | 103 if (guarded) |
| 97 return false; | 104 return; |
| 98 | 105 |
| 99 base::AutoReset<bool> guard(&guarded, true); | 106 base::AutoReset<bool> guard(&guarded, true); |
| 100 | 107 |
| 101 // Only log last path component. This matches logging.cc. | 108 // Only log last path component. This matches logging.cc. |
| 102 if (file) { | 109 if (file) { |
| 103 const char* slash = strrchr(file, '/'); | 110 const char* slash = strrchr(file, '/'); |
| 104 if (slash) | 111 if (slash) |
| 105 file = slash + 1; | 112 file = slash + 1; |
| 106 } | 113 } |
| 107 | 114 |
| 108 NSString* fatal_key = @"LOG_FATAL"; | 115 NSString* fatal_key = @"LOG_FATAL"; |
| 109 NSString* fatal_value = [NSString | 116 NSString* fatal_value = [NSString |
| 110 stringWithFormat:@"%s:%d: %s", file, line, str.c_str() + message_start]; | 117 stringWithFormat:@"%s:%d: %s", file, line, str.c_str() + message_start]; |
| 111 AddReportParameter(fatal_key, fatal_value, true); | 118 AddReportParameter(fatal_key, fatal_value, true); |
| 112 | 119 |
| 113 // Rather than including the code to force the crash here, allow the | 120 // Rather than including the code to force the crash here, allow the |
| 114 // caller to do it. | 121 // caller to do it. |
| 115 return false; | |
| 116 } | 122 } |
| 117 | 123 |
| 118 // Caches the uploading flag in NSUserDefaults, so that we can access the value | 124 // Caches the uploading flag in NSUserDefaults, so that we can access the value |
| 119 // in safe mode. | 125 // in safe mode. |
| 120 void CacheUploadingEnabled(bool uploading_enabled) { | 126 void CacheUploadingEnabled(bool uploading_enabled) { |
| 121 NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; | 127 NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; |
| 122 [user_defaults setBool:uploading_enabled ? YES : NO | 128 [user_defaults setBool:uploading_enabled ? YES : NO |
| 123 forKey:kCrashReportsUploadingEnabledKey]; | 129 forKey:kCrashReportsUploadingEnabledKey]; |
| 124 } | 130 } |
| 125 | 131 |
| 126 } // namespace | 132 } // namespace |
| 127 | 133 |
| 128 void Start(const std::string& channel_name) { | 134 void Start(const std::string& channel_name) { |
| 129 DCHECK(!g_crash_reporter_enabled); | 135 DCHECK(!g_crash_reporter_enabled); |
| 130 [[BreakpadController sharedInstance] start:YES]; | 136 [[BreakpadController sharedInstance] start:YES]; |
| 131 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValueImpl, | 137 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValueImpl, |
| 132 &ClearCrashKeyValueImpl); | 138 &ClearCrashKeyValueImpl); |
| 133 logging::SetLogMessageHandler(&FatalMessageHandler); | 139 // Intentionally leak the listener. |
| 140 auto* listener = new FatalMessageListener(); |
| 141 CHECK(listener); |
| 142 |
| 134 g_crash_reporter_enabled = true; | 143 g_crash_reporter_enabled = true; |
| 135 // Register channel information. | 144 // Register channel information. |
| 136 if (channel_name.length()) { | 145 if (channel_name.length()) { |
| 137 AddReportParameter(@"channel", base::SysUTF8ToNSString(channel_name), true); | 146 AddReportParameter(@"channel", base::SysUTF8ToNSString(channel_name), true); |
| 138 } | 147 } |
| 139 // Notifying the PathService on the location of the crashes so that crashes | 148 // Notifying the PathService on the location of the crashes so that crashes |
| 140 // can be displayed to the user on the about:crashes page. | 149 // can be displayed to the user on the about:crashes page. |
| 141 NSArray* cachesDirectories = NSSearchPathForDirectoriesInDomains( | 150 NSArray* cachesDirectories = NSSearchPathForDirectoriesInDomains( |
| 142 NSCachesDirectory, NSUserDomainMask, YES); | 151 NSCachesDirectory, NSUserDomainMask, YES); |
| 143 NSString* cachePath = [cachesDirectories objectAtIndex:0]; | 152 NSString* cachePath = [cachesDirectories objectAtIndex:0]; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 void RestoreDefaultConfiguration() { | 369 void RestoreDefaultConfiguration() { |
| 361 if (!g_crash_reporter_enabled) | 370 if (!g_crash_reporter_enabled) |
| 362 return; | 371 return; |
| 363 [[BreakpadController sharedInstance] stop]; | 372 [[BreakpadController sharedInstance] stop]; |
| 364 [[BreakpadController sharedInstance] resetConfiguration]; | 373 [[BreakpadController sharedInstance] resetConfiguration]; |
| 365 [[BreakpadController sharedInstance] start:NO]; | 374 [[BreakpadController sharedInstance] start:NO]; |
| 366 [[BreakpadController sharedInstance] setUploadingEnabled:NO]; | 375 [[BreakpadController sharedInstance] setUploadingEnabled:NO]; |
| 367 } | 376 } |
| 368 | 377 |
| 369 } // namespace breakpad_helper | 378 } // namespace breakpad_helper |
| OLD | NEW |