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/base_switches.h" | 10 #include "base/base_switches.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 } | 43 } |
44 | 44 |
45 void ClearCrashKeyValue(NSString* key) { | 45 void ClearCrashKeyValue(NSString* key) { |
46 if (gBreakpadRef == NULL) { | 46 if (gBreakpadRef == NULL) { |
47 return; | 47 return; |
48 } | 48 } |
49 | 49 |
50 BreakpadRemoveUploadParameter(gBreakpadRef, key); | 50 BreakpadRemoveUploadParameter(gBreakpadRef, key); |
51 } | 51 } |
52 | 52 |
53 bool FatalMessageHandler(int severity, const char* file, int line, | |
54 size_t message_start, const std::string& str) { | |
55 // Do not handle non-FATAL. | |
56 if (severity != logging::LOG_FATAL) | |
57 return false; | |
58 | |
59 // Only log last path component. This matches logging.cc. | |
60 // NOTE(shess): Could look for the shared prefix between |file| and | |
Mark Mentovai
2011/10/26 23:50:27
If this were to become a fully-cooked idea, it wou
Scott Hess - ex-Googler
2011/10/27 00:15:09
removed.
| |
61 // |__FILE__|, and store what's left. | |
62 if (file) { | |
63 const char* slash = rindex(file, '/'); | |
Mark Mentovai
2011/10/26 23:50:27
strrchr is the modern name for rindex. Use that.
Scott Hess - ex-Googler
2011/10/27 00:15:09
GET OFF MY LAWN!
| |
64 if (slash) | |
65 file = slash + 1; | |
Mark Mentovai
2011/10/26 23:50:27
If file is an empty string, this is dangerous. Be
dmac
2011/10/27 00:07:11
if file is an empty string, won't slash be NULL? a
Scott Hess - ex-Googler
2011/10/27 00:15:09
If file were empty, slash would be NULL.
| |
66 } | |
67 | |
68 // What happens if we ran out of memory and the construction does a | |
Mark Mentovai
2011/10/26 23:50:27
You know how I feel about “we.”
Scott Hess - ex-Googler
2011/10/27 00:15:09
Bother.
| |
69 // malloc? Infinite loop! By putting a CHECK() in this code, I | |
70 // verified that it still crashed after running out of stack... | |
71 // Solving would maybe need a pre-allocated mutable string? | |
Mark Mentovai
2011/10/26 23:50:27
You can have a static bool that gets set when you
Scott Hess - ex-Googler
2011/10/27 00:15:09
I think that's reasonable. I'll put that up as a
| |
72 NSString* fatal_key = @"LOG_FATAL"; | |
73 NSString* fatal_value = | |
74 [NSString stringWithFormat:@"%s:%d: %s", | |
75 file, line, str.c_str() + message_start]; | |
76 SetCrashKeyValue(fatal_key, fatal_value); | |
77 | |
78 // Rather than including the code to force the crash here, allow the | |
79 // caller to do it. | |
80 return false; | |
81 } | |
82 | |
53 } // namespace | 83 } // namespace |
54 | 84 |
55 bool IsCrashReporterEnabled() { | 85 bool IsCrashReporterEnabled() { |
56 return gBreakpadRef != NULL; | 86 return gBreakpadRef != NULL; |
57 } | 87 } |
58 | 88 |
59 // Only called for a branded build of Chrome.app. | 89 // Only called for a branded build of Chrome.app. |
60 void InitCrashReporter() { | 90 void InitCrashReporter() { |
61 DCHECK(!gBreakpadRef); | 91 DCHECK(!gBreakpadRef); |
62 base::mac::ScopedNSAutoreleasePool autorelease_pool; | 92 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. | 199 // Enable child process crashes to include the page URL. |
170 // TODO: Should this only be done for certain process types? | 200 // TODO: Should this only be done for certain process types? |
171 base::mac::SetCrashKeyFunctions(SetCrashKeyValue, | 201 base::mac::SetCrashKeyFunctions(SetCrashKeyValue, |
172 ClearCrashKeyValue); | 202 ClearCrashKeyValue); |
173 | 203 |
174 if (!is_browser) { | 204 if (!is_browser) { |
175 // Get the guid from the command line switch. | 205 // Get the guid from the command line switch. |
176 std::string guid = | 206 std::string guid = |
177 command_line->GetSwitchValueASCII(switches::kEnableCrashReporter); | 207 command_line->GetSwitchValueASCII(switches::kEnableCrashReporter); |
178 child_process_logging::SetClientId(guid); | 208 child_process_logging::SetClientId(guid); |
179 } | 209 } |
210 | |
211 logging::SetLogMessageHandler(&FatalMessageHandler); | |
180 } | 212 } |
181 | 213 |
182 void InitCrashProcessInfo() { | 214 void InitCrashProcessInfo() { |
183 if (gBreakpadRef == NULL) { | 215 if (gBreakpadRef == NULL) { |
184 return; | 216 return; |
185 } | 217 } |
186 | 218 |
187 // Determine the process type. | 219 // Determine the process type. |
188 NSString* process_type = @"browser"; | 220 NSString* process_type = @"browser"; |
189 std::string process_type_switch = | 221 std::string process_type_switch = |
190 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 222 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
191 switches::kProcessType); | 223 switches::kProcessType); |
192 if (!process_type_switch.empty()) { | 224 if (!process_type_switch.empty()) { |
193 process_type = base::SysUTF8ToNSString(process_type_switch); | 225 process_type = base::SysUTF8ToNSString(process_type_switch); |
194 } | 226 } |
195 | 227 |
196 // Store process type in crash dump. | 228 // Store process type in crash dump. |
197 SetCrashKeyValue(@"ptype", process_type); | 229 SetCrashKeyValue(@"ptype", process_type); |
198 } | 230 } |
OLD | NEW |