OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import "chrome/app/breakpad_mac.h" | 5 #import "chrome/app/breakpad_mac.h" |
6 | 6 |
7 #include <CoreFoundation/CoreFoundation.h> | 7 #include <CoreFoundation/CoreFoundation.h> |
8 #import <Foundation/Foundation.h> | 8 #import <Foundation/Foundation.h> |
9 | 9 |
| 10 #include "base/auto_reset.h" |
10 #include "base/base_switches.h" | 11 #include "base/base_switches.h" |
11 #import "base/basictypes.h" | 12 #import "base/basictypes.h" |
12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
13 #include "base/file_path.h" | 14 #include "base/file_path.h" |
14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
15 #import "base/logging.h" | 16 #import "base/logging.h" |
16 #include "base/mac/mac_util.h" | 17 #include "base/mac/mac_util.h" |
17 #include "base/mac/scoped_cftyperef.h" | 18 #include "base/mac/scoped_cftyperef.h" |
18 #import "base/mac/scoped_nsautorelease_pool.h" | 19 #import "base/mac/scoped_nsautorelease_pool.h" |
19 #include "base/path_service.h" | 20 #include "base/path_service.h" |
(...skipping 23 matching lines...) Expand all Loading... |
43 } | 44 } |
44 | 45 |
45 void ClearCrashKeyValue(NSString* key) { | 46 void ClearCrashKeyValue(NSString* key) { |
46 if (gBreakpadRef == NULL) { | 47 if (gBreakpadRef == NULL) { |
47 return; | 48 return; |
48 } | 49 } |
49 | 50 |
50 BreakpadRemoveUploadParameter(gBreakpadRef, key); | 51 BreakpadRemoveUploadParameter(gBreakpadRef, key); |
51 } | 52 } |
52 | 53 |
| 54 bool FatalMessageHandler(int severity, const char* file, int line, |
| 55 size_t message_start, const std::string& str) { |
| 56 // Do not handle non-FATAL. |
| 57 if (severity != logging::LOG_FATAL) |
| 58 return false; |
| 59 |
| 60 // In case of OOM condition, this code could be reentered when |
| 61 // constructing and storing the key. Using a static is not |
| 62 // thread-safe, but if multiple threads are in the process of a |
| 63 // fatal crash at the same time, this should work. |
| 64 static bool guarded = false; |
| 65 if (guarded) |
| 66 return false; |
| 67 |
| 68 AutoReset<bool> guard(&guarded, true); |
| 69 |
| 70 // Only log last path component. This matches logging.cc. |
| 71 if (file) { |
| 72 const char* slash = strrchr(file, '/'); |
| 73 if (slash) |
| 74 file = slash + 1; |
| 75 } |
| 76 |
| 77 NSString* fatal_key = @"LOG_FATAL"; |
| 78 NSString* fatal_value = |
| 79 [NSString stringWithFormat:@"%s:%d: %s", |
| 80 file, line, str.c_str() + message_start]; |
| 81 SetCrashKeyValue(fatal_key, fatal_value); |
| 82 |
| 83 // Rather than including the code to force the crash here, allow the |
| 84 // caller to do it. |
| 85 return false; |
| 86 } |
| 87 |
53 } // namespace | 88 } // namespace |
54 | 89 |
55 bool IsCrashReporterEnabled() { | 90 bool IsCrashReporterEnabled() { |
56 return gBreakpadRef != NULL; | 91 return gBreakpadRef != NULL; |
57 } | 92 } |
58 | 93 |
59 // Only called for a branded build of Chrome.app. | 94 // Only called for a branded build of Chrome.app. |
60 void InitCrashReporter() { | 95 void InitCrashReporter() { |
61 DCHECK(!gBreakpadRef); | 96 DCHECK(!gBreakpadRef); |
62 base::mac::ScopedNSAutoreleasePool autorelease_pool; | 97 base::mac::ScopedNSAutoreleasePool autorelease_pool; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // Enable child process crashes to include the page URL. | 204 // Enable child process crashes to include the page URL. |
170 // TODO: Should this only be done for certain process types? | 205 // TODO: Should this only be done for certain process types? |
171 base::mac::SetCrashKeyFunctions(SetCrashKeyValue, | 206 base::mac::SetCrashKeyFunctions(SetCrashKeyValue, |
172 ClearCrashKeyValue); | 207 ClearCrashKeyValue); |
173 | 208 |
174 if (!is_browser) { | 209 if (!is_browser) { |
175 // Get the guid from the command line switch. | 210 // Get the guid from the command line switch. |
176 std::string guid = | 211 std::string guid = |
177 command_line->GetSwitchValueASCII(switches::kEnableCrashReporter); | 212 command_line->GetSwitchValueASCII(switches::kEnableCrashReporter); |
178 child_process_logging::SetClientId(guid); | 213 child_process_logging::SetClientId(guid); |
179 } | 214 } |
| 215 |
| 216 logging::SetLogMessageHandler(&FatalMessageHandler); |
180 } | 217 } |
181 | 218 |
182 void InitCrashProcessInfo() { | 219 void InitCrashProcessInfo() { |
183 if (gBreakpadRef == NULL) { | 220 if (gBreakpadRef == NULL) { |
184 return; | 221 return; |
185 } | 222 } |
186 | 223 |
187 // Determine the process type. | 224 // Determine the process type. |
188 NSString* process_type = @"browser"; | 225 NSString* process_type = @"browser"; |
189 std::string process_type_switch = | 226 std::string process_type_switch = |
190 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 227 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
191 switches::kProcessType); | 228 switches::kProcessType); |
192 if (!process_type_switch.empty()) { | 229 if (!process_type_switch.empty()) { |
193 process_type = base::SysUTF8ToNSString(process_type_switch); | 230 process_type = base::SysUTF8ToNSString(process_type_switch); |
194 } | 231 } |
195 | 232 |
196 // Store process type in crash dump. | 233 // Store process type in crash dump. |
197 SetCrashKeyValue(@"ptype", process_type); | 234 SetCrashKeyValue(@"ptype", process_type); |
198 } | 235 } |
OLD | NEW |