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

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

Issue 345051: Cleans up our autorelease handling so that we don't create a layered ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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_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/cocoa/chrome_event_processing_window.h" 12 #import "chrome/browser/cocoa/chrome_event_processing_window.h"
13 #import "chrome/browser/cocoa/objc_method_swizzle.h" 13 #import "chrome/browser/cocoa/objc_method_swizzle.h"
14 #import "chrome/browser/renderer_host/render_widget_host_view_mac.h"
15 14
16 // The implementation of NSExceptions break various assumptions in the 15 // The implementation of NSExceptions break various assumptions in the
17 // Chrome code. This category defines a replacement for 16 // Chrome code. This category defines a replacement for
18 // -initWithName:reason:userInfo: for purposes of forcing a break in 17 // -initWithName:reason:userInfo: for purposes of forcing a break in
19 // the debugger when an exception is raised. -raise sounds more 18 // the debugger when an exception is raised. -raise sounds more
20 // obvious to intercept, but it doesn't catch the original throw 19 // obvious to intercept, but it doesn't catch the original throw
21 // because the objc runtime doesn't use it. 20 // because the objc runtime doesn't use it.
22 @interface NSException (NSExceptionSwizzle) 21 @interface NSException (NSExceptionSwizzle)
23 - (id)chromeInitWithName:(NSString *)aName 22 - (id)chromeInitWithName:(NSString *)aName
24 reason:(NSString *)aReason 23 reason:(NSString *)aReason
(...skipping 17 matching lines...) Expand all
42 DLOG(ERROR) << "Someone is preparing to raise an exception! " 41 DLOG(ERROR) << "Someone is preparing to raise an exception! "
43 << base::SysNSStringToUTF8(aName) << " *** " 42 << base::SysNSStringToUTF8(aName) << " *** "
44 << base::SysNSStringToUTF8(aReason); 43 << base::SysNSStringToUTF8(aReason);
45 NOTREACHED(); 44 NOTREACHED();
46 45
47 // Forward to the original version. 46 // Forward to the original version.
48 return gOriginalInitIMP(self, _cmd, aName, aReason, someUserInfo); 47 return gOriginalInitIMP(self, _cmd, aName, aReason, someUserInfo);
49 } 48 }
50 @end 49 @end
51 50
52 namespace CrApplicationNSException { 51 namespace chrome_browser_application_mac {
53 52
54 // Maximum number of known named exceptions we'll support. There is 53 // Maximum number of known named exceptions we'll support. There is
55 // no central registration, but I only find about 75 possibilities in 54 // no central registration, but I only find about 75 possibilities in
56 // the system frameworks, and many of them are probably not 55 // the system frameworks, and many of them are probably not
57 // interesting to track in aggregate (those relating to distributed 56 // interesting to track in aggregate (those relating to distributed
58 // objects, for instance). 57 // objects, for instance).
59 const size_t kKnownNSExceptionCount = 25; 58 const size_t kKnownNSExceptionCount = 25;
60 59
61 const size_t kUnknownNSException = kKnownNSExceptionCount; 60 const size_t kUnknownNSException = kKnownNSExceptionCount;
62 61
(...skipping 29 matching lines...) Expand all
92 return kUnknownNSException; 91 return kUnknownNSException;
93 } 92 }
94 93
95 void RecordExceptionWithUma(NSException* exception) { 94 void RecordExceptionWithUma(NSException* exception) {
96 static LinearHistogram histogram("OSX.NSException", 0, kUnknownNSException, 95 static LinearHistogram histogram("OSX.NSException", 0, kUnknownNSException,
97 kUnknownNSException + 1); 96 kUnknownNSException + 1);
98 histogram.SetFlags(kUmaTargetedHistogramFlag); 97 histogram.SetFlags(kUmaTargetedHistogramFlag);
99 histogram.Add(BinForException(exception)); 98 histogram.Add(BinForException(exception));
100 } 99 }
101 100
102 } // CrApplicationNSException 101 void Terminate() {
102 [NSApp terminate:nil];
103 }
104
105 } // namespace chrome_browser_application_mac
103 106
104 namespace { 107 namespace {
105 108
106 // Helper to make it easy to get crash keys right. 109 // Helper to make it easy to get crash keys right.
107 // TODO(shess): Find a better home for this. app/breakpad_mac.h 110 // TODO(shess): Find a better home for this. app/breakpad_mac.h
108 // doesn't work. 111 // doesn't work.
109 class ScopedCrashKey { 112 class ScopedCrashKey {
110 public: 113 public:
111 ScopedCrashKey(NSString* key, NSString* value) 114 ScopedCrashKey(NSString* key, NSString* value)
112 : crash_key_([key retain]) { 115 : crash_key_([key retain]) {
(...skipping 13 matching lines...) Expand all
126 BOOL SwizzleNSExceptionInit() { 129 BOOL SwizzleNSExceptionInit() {
127 gOriginalInitIMP = ObjcEvilDoers::SwizzleImplementedInstanceMethods( 130 gOriginalInitIMP = ObjcEvilDoers::SwizzleImplementedInstanceMethods(
128 [NSException class], 131 [NSException class],
129 @selector(initWithName:reason:userInfo:), 132 @selector(initWithName:reason:userInfo:),
130 @selector(chromeInitWithName:reason:userInfo:)); 133 @selector(chromeInitWithName:reason:userInfo:));
131 return YES; 134 return YES;
132 } 135 }
133 136
134 } // namespace 137 } // namespace
135 138
136 @implementation CrApplication 139 @implementation BrowserCrApplication
137 140
138 - init { 141 - init {
139 // TODO(shess): Push this somewhere where it can apply to the plugin
140 // and renderer processes, and where it can intercept uncaught
141 // exceptions.
142 DCHECK(SwizzleNSExceptionInit()); 142 DCHECK(SwizzleNSExceptionInit());
143 return [super init]; 143 return [super init];
144 } 144 }
145 145
146 // -terminate: is the entry point for orderly "quit" operations in Cocoa. 146 // -terminate: is the entry point for orderly "quit" operations in Cocoa.
147 // This includes the application menu's quit menu item and keyboard 147 // This includes the application menu's quit menu item and keyboard
148 // equivalent, the application's dock icon menu's quit menu item, "quit" (not 148 // equivalent, the application's dock icon menu's quit menu item, "quit" (not
149 // "force quit") in the Activity Monitor, and quits triggered by user logout 149 // "force quit") in the Activity Monitor, and quits triggered by user logout
150 // and system restart and shutdown. 150 // and system restart and shutdown.
151 // 151 //
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 NSString* actionString = NSStringFromSelector(anAction); 237 NSString* actionString = NSStringFromSelector(anAction);
238 NSString* value = 238 NSString* value =
239 [NSString stringWithFormat:@"%@ tag %d sending %@ to %p", 239 [NSString stringWithFormat:@"%@ tag %d sending %@ to %p",
240 [sender className], tag, actionString, aTarget]; 240 [sender className], tag, actionString, aTarget];
241 241
242 ScopedCrashKey key(kActionKey, value); 242 ScopedCrashKey key(kActionKey, value);
243 return [super sendAction:anAction to:aTarget from:sender]; 243 return [super sendAction:anAction to:aTarget from:sender];
244 } 244 }
245 245
246 - (void)sendEvent:(NSEvent*)event { 246 - (void)sendEvent:(NSEvent*)event {
247 chrome_application_mac::ScopedSendingEvent scoper(self);
247 // The superclass's |sendEvent:| sends keyboard events to the menu and the key 248 // The superclass's |sendEvent:| sends keyboard events to the menu and the key
248 // view loop before dispatching them to |keyDown:|. Since we want to send keys 249 // view loop before dispatching them to |keyDown:|. Since we want to send keys
249 // to the renderer before sending them to the menu, and we never want them to 250 // to the renderer before sending them to the menu, and we never want them to
250 // the kev view loop when the web is focussed, we change this behavior. 251 // the kev view loop when the web is focussed, we change this behavior.
251 if ([[self keyWindow] 252 if ([[self keyWindow]
252 isKindOfClass:[ChromeEventProcessingWindow class]]) { 253 isKindOfClass:[ChromeEventProcessingWindow class]]) {
253 if ([static_cast<ChromeEventProcessingWindow*>([self keyWindow]) 254 if ([static_cast<ChromeEventProcessingWindow*>([self keyWindow])
254 shortcircuitEvent:event]) 255 shortcircuitEvent:event])
255 return; 256 return;
256 } 257 }
257 258
258 [super sendEvent:event]; 259 [super sendEvent:event];
259 } 260 }
260 261
261 // NSExceptions which are caught by the event loop are logged here. 262 // NSExceptions which are caught by the event loop are logged here.
262 // NSException uses setjmp/longjmp, which can be very bad for C++, so 263 // NSException uses setjmp/longjmp, which can be very bad for C++, so
263 // we attempt to track and report them. 264 // we attempt to track and report them.
264 - (void)reportException:(NSException *)anException { 265 - (void)reportException:(NSException *)anException {
265 // If we throw an exception in this code, we can create an infinite 266 // If we throw an exception in this code, we can create an infinite
266 // loop. If we throw out of the if() without resetting 267 // loop. If we throw out of the if() without resetting
267 // |reportException|, we'll stop reporting exceptions for this run. 268 // |reportException|, we'll stop reporting exceptions for this run.
268 static BOOL reportingException = NO; 269 static BOOL reportingException = NO;
269 DCHECK(!reportingException); 270 DCHECK(!reportingException);
270 if (!reportingException) { 271 if (!reportingException) {
271 reportingException = YES; 272 reportingException = YES;
272 CrApplicationNSException::RecordExceptionWithUma(anException); 273 chrome_browser_application_mac::RecordExceptionWithUma(anException);
273 274
274 // Store some human-readable information in breakpad keys in case 275 // Store some human-readable information in breakpad keys in case
275 // there is a crash. Since breakpad does not provide infinite 276 // there is a crash. Since breakpad does not provide infinite
276 // storage, we track two exceptions. The first exception thrown 277 // storage, we track two exceptions. The first exception thrown
277 // is tracked because it may be the one which caused the system to 278 // is tracked because it may be the one which caused the system to
278 // go off the rails. The last exception thrown is tracked because 279 // go off the rails. The last exception thrown is tracked because
279 // it may be the one most directly associated with the crash. 280 // it may be the one most directly associated with the crash.
280 static const NSString* kFirstExceptionKey = @"firstexception"; 281 static const NSString* kFirstExceptionKey = @"firstexception";
281 static BOOL trackedFirstException = NO; 282 static BOOL trackedFirstException = NO;
282 static const NSString* kLastExceptionKey = @"lastexception"; 283 static const NSString* kLastExceptionKey = @"lastexception";
(...skipping 16 matching lines...) Expand all
299 SetCrashKeyValue(kLastExceptionKey, value); 300 SetCrashKeyValue(kLastExceptionKey, value);
300 } 301 }
301 302
302 reportingException = NO; 303 reportingException = NO;
303 } 304 }
304 305
305 [super reportException:anException]; 306 [super reportException:anException];
306 } 307 }
307 308
308 @end 309 @end
309
310 namespace CrApplicationCC {
311
312 void Terminate() {
313 [NSApp terminate:nil];
314 }
315
316 } // namespace CrApplicationCC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698