Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: chrome/browser/chrome_browser_application_mac.mm

Issue 2769014: Mac/clang: Possibly contentious changes. (Closed)
Patch Set: comments2 Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/browser/chrome_browser_application_mac.h" 5 #import "chrome/browser/chrome_browser_application_mac.h"
6 6
7 #import "base/histogram.h" 7 #import "base/histogram.h"
8 #import "base/logging.h" 8 #import "base/logging.h"
9 #import "base/scoped_nsobject.h" 9 #import "base/scoped_nsobject.h"
10 #import "base/sys_string_conversions.h" 10 #import "base/sys_string_conversions.h"
11 #import "chrome/app/breakpad_mac.h" 11 #import "chrome/app/breakpad_mac.h"
12 #import "chrome/browser/app_controller_mac.h" 12 #import "chrome/browser/app_controller_mac.h"
13 #import "chrome/browser/cocoa/objc_method_swizzle.h" 13 #import "chrome/browser/cocoa/objc_method_swizzle.h"
14 #import "chrome/browser/cocoa/objc_zombie.h" 14 #import "chrome/browser/cocoa/objc_zombie.h"
15 15
16 // The implementation of NSExceptions break various assumptions in the 16 // The implementation of NSExceptions break various assumptions in the
17 // Chrome code. This category defines a replacement for 17 // Chrome code. This category defines a replacement for
18 // -initWithName:reason:userInfo: for purposes of forcing a break in 18 // -initWithName:reason:userInfo: for purposes of forcing a break in
19 // the debugger when an exception is raised. -raise sounds more 19 // the debugger when an exception is raised. -raise sounds more
20 // obvious to intercept, but it doesn't catch the original throw 20 // obvious to intercept, but it doesn't catch the original throw
21 // because the objc runtime doesn't use it. 21 // because the objc runtime doesn't use it.
22 @interface NSException (NSExceptionSwizzle) 22 @interface NSException (NSExceptionSwizzle)
23 - (id)chromeInitWithName:(NSString *)aName 23 - (id)chromeInitWithName:(NSString*)aName
24 reason:(NSString *)aReason 24 reason:(NSString*)aReason
25 userInfo:(NSDictionary *)someUserInfo; 25 userInfo:(NSDictionary *)someUserInfo;
26 @end 26 @end
27 27
28 static IMP gOriginalInitIMP = NULL; 28 static IMP gOriginalInitIMP = NULL;
29 29
30 @implementation NSException (NSExceptionSwizzle) 30 @implementation NSException (NSExceptionSwizzle)
31 - (id)chromeInitWithName:(NSString *)aName 31 - (id)chromeInitWithName:(NSString*)aName
32 reason:(NSString *)aReason 32 reason:(NSString*)aReason
33 userInfo:(NSDictionary *)someUserInfo { 33 userInfo:(NSDictionary *)someUserInfo {
34 // Method only called when swizzled. 34 // Method only called when swizzled.
35 DCHECK(_cmd == @selector(initWithName:reason:userInfo:)); 35 DCHECK(_cmd == @selector(initWithName:reason:userInfo:));
36 36
37 // Parts of Cocoa rely on creating and throwing exceptions. These are not 37 // Parts of Cocoa rely on creating and throwing exceptions. These are not
38 // worth bugging-out over. It is very important that there be zero chance that 38 // worth bugging-out over. It is very important that there be zero chance that
39 // any Chromium code is on the stack; these must be created by Apple code and 39 // any Chromium code is on the stack; these must be created by Apple code and
40 // then immediately consumed by Apple code. 40 // then immediately consumed by Apple code.
41 static const NSString* kAcceptableNSExceptionNames[] = { 41 static NSString* const kAcceptableNSExceptionNames[] = {
42 // If an object does not support an accessibility attribute, this will 42 // If an object does not support an accessibility attribute, this will
43 // get thrown. 43 // get thrown.
44 NSAccessibilityException, 44 NSAccessibilityException,
45 45
46 nil 46 nil
47 }; 47 };
48 48
49 BOOL found = NO; 49 BOOL found = NO;
50 for (int i = 0; kAcceptableNSExceptionNames[i]; ++i) { 50 for (int i = 0; kAcceptableNSExceptionNames[i]; ++i) {
51 if (aName == kAcceptableNSExceptionNames[i]) { 51 if (aName == kAcceptableNSExceptionNames[i]) {
(...skipping 26 matching lines...) Expand all
78 // interesting to track in aggregate (those relating to distributed 78 // interesting to track in aggregate (those relating to distributed
79 // objects, for instance). 79 // objects, for instance).
80 const size_t kKnownNSExceptionCount = 25; 80 const size_t kKnownNSExceptionCount = 25;
81 81
82 const size_t kUnknownNSException = kKnownNSExceptionCount; 82 const size_t kUnknownNSException = kKnownNSExceptionCount;
83 83
84 size_t BinForException(NSException* exception) { 84 size_t BinForException(NSException* exception) {
85 // A list of common known exceptions. The list position will 85 // A list of common known exceptions. The list position will
86 // determine where they live in the histogram, so never move them 86 // determine where they live in the histogram, so never move them
87 // around, only add to the end. 87 // around, only add to the end.
88 static const NSString* kKnownNSExceptionNames[] = { 88 static NSString* const kKnownNSExceptionNames[] = {
89 // ??? 89 // ???
90 NSGenericException, 90 NSGenericException,
91 91
92 // Out-of-range on NSString or NSArray. 92 // Out-of-range on NSString or NSArray.
93 NSRangeException, 93 NSRangeException,
94 94
95 // Invalid arg to method, unrecognized selector. 95 // Invalid arg to method, unrecognized selector.
96 NSInvalidArgumentException, 96 NSInvalidArgumentException,
97 97
98 // malloc() returned null in object creation, I think. 98 // malloc() returned null in object creation, I think.
99 NSMallocException, 99 NSMallocException,
100 100
101 nil 101 nil
102 }; 102 };
103 103
104 // Make sure our array hasn't outgrown our abilities to track it. 104 // Make sure our array hasn't outgrown our abilities to track it.
105 DCHECK_LE(arraysize(kKnownNSExceptionNames), kKnownNSExceptionCount); 105 DCHECK_LE(arraysize(kKnownNSExceptionNames), kKnownNSExceptionCount);
106 106
107 const NSString* name = [exception name]; 107 NSString* name = [exception name];
108 for (int i = 0; kKnownNSExceptionNames[i]; ++i) { 108 for (int i = 0; kKnownNSExceptionNames[i]; ++i) {
109 if (name == kKnownNSExceptionNames[i]) { 109 if (name == kKnownNSExceptionNames[i]) {
110 return i; 110 return i;
111 } 111 }
112 } 112 }
113 return kUnknownNSException; 113 return kUnknownNSException;
114 } 114 }
115 115
116 void RecordExceptionWithUma(NSException* exception) { 116 void RecordExceptionWithUma(NSException* exception) {
117 UMA_HISTOGRAM_ENUMERATION("OSX.NSException", 117 UMA_HISTOGRAM_ENUMERATION("OSX.NSException",
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 269 }
270 } 270 }
271 if (!found) { 271 if (!found) {
272 return NO; 272 return NO;
273 } 273 }
274 } 274 }
275 275
276 // When a Cocoa control is wired to a freed object, we get crashers 276 // When a Cocoa control is wired to a freed object, we get crashers
277 // in the call to |super| with no useful information in the 277 // in the call to |super| with no useful information in the
278 // backtrace. Attempt to add some useful information. 278 // backtrace. Attempt to add some useful information.
279 static const NSString* kActionKey = @"sendaction"; 279 static NSString* const kActionKey = @"sendaction";
280 280
281 // If the action is something generic like -commandDispatch:, then 281 // If the action is something generic like -commandDispatch:, then
282 // the tag is essential. 282 // the tag is essential.
283 NSInteger tag = 0; 283 NSInteger tag = 0;
284 if ([sender isKindOfClass:[NSControl class]]) { 284 if ([sender isKindOfClass:[NSControl class]]) {
285 tag = [sender tag]; 285 tag = [sender tag];
286 if (tag == 0 || tag == -1) { 286 if (tag == 0 || tag == -1) {
287 tag = [sender selectedTag]; 287 tag = [sender selectedTag];
288 } 288 }
289 } else if ([sender isKindOfClass:[NSMenuItem class]]) { 289 } else if ([sender isKindOfClass:[NSMenuItem class]]) {
(...skipping 21 matching lines...) Expand all
311 if (!reportingException) { 311 if (!reportingException) {
312 reportingException = YES; 312 reportingException = YES;
313 chrome_browser_application_mac::RecordExceptionWithUma(anException); 313 chrome_browser_application_mac::RecordExceptionWithUma(anException);
314 314
315 // Store some human-readable information in breakpad keys in case 315 // Store some human-readable information in breakpad keys in case
316 // there is a crash. Since breakpad does not provide infinite 316 // there is a crash. Since breakpad does not provide infinite
317 // storage, we track two exceptions. The first exception thrown 317 // storage, we track two exceptions. The first exception thrown
318 // is tracked because it may be the one which caused the system to 318 // is tracked because it may be the one which caused the system to
319 // go off the rails. The last exception thrown is tracked because 319 // go off the rails. The last exception thrown is tracked because
320 // it may be the one most directly associated with the crash. 320 // it may be the one most directly associated with the crash.
321 static const NSString* kFirstExceptionKey = @"firstexception"; 321 static NSString* const kFirstExceptionKey = @"firstexception";
322 static BOOL trackedFirstException = NO; 322 static BOOL trackedFirstException = NO;
323 static const NSString* kLastExceptionKey = @"lastexception"; 323 static NSString* const kLastExceptionKey = @"lastexception";
324 324
325 // TODO(shess): It would be useful to post some stacktrace info 325 // TODO(shess): It would be useful to post some stacktrace info
326 // from the exception. 326 // from the exception.
327 // 10.6 has -[NSException callStackSymbols] 327 // 10.6 has -[NSException callStackSymbols]
328 // 10.5 has -[NSException callStackReturnAddresses] 328 // 10.5 has -[NSException callStackReturnAddresses]
329 // 10.5 has backtrace_symbols(). 329 // 10.5 has backtrace_symbols().
330 // I've tried to combine the latter two, but got nothing useful. 330 // I've tried to combine the latter two, but got nothing useful.
331 // The addresses are right, though, maybe we could train the crash 331 // The addresses are right, though, maybe we could train the crash
332 // server to decode them for us. 332 // server to decode them for us.
333 333
334 NSString* value = [NSString stringWithFormat:@"%@ reason %@", 334 NSString* value = [NSString stringWithFormat:@"%@ reason %@",
335 [anException name], [anException reason]]; 335 [anException name], [anException reason]];
336 if (!trackedFirstException) { 336 if (!trackedFirstException) {
337 SetCrashKeyValue(kFirstExceptionKey, value); 337 SetCrashKeyValue(kFirstExceptionKey, value);
338 trackedFirstException = YES; 338 trackedFirstException = YES;
339 } else { 339 } else {
340 SetCrashKeyValue(kLastExceptionKey, value); 340 SetCrashKeyValue(kLastExceptionKey, value);
341 } 341 }
342 342
343 reportingException = NO; 343 reportingException = NO;
344 } 344 }
345 345
346 [super reportException:anException]; 346 [super reportException:anException];
347 } 347 }
348 348
349 @end 349 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698