Index: chrome/browser/chrome_browser_application_mac.mm |
diff --git a/chrome/browser/chrome_browser_application_mac.mm b/chrome/browser/chrome_browser_application_mac.mm |
index 5a63b9f03ebecf9a81ed2bf24256cdf933e70347..63f3b083091c027b0c39ae953b6d5d4cd26a38b1 100644 |
--- a/chrome/browser/chrome_browser_application_mac.mm |
+++ b/chrome/browser/chrome_browser_application_mac.mm |
@@ -4,120 +4,22 @@ |
#import "chrome/browser/chrome_browser_application_mac.h" |
-#include <AvailabilityMacros.h> |
-#include <objc/objc-exception.h> |
- |
-#import "base/auto_reset.h" |
+#include "base/auto_reset.h" |
#include "base/command_line.h" |
#include "base/debug/crash_logging.h" |
-#include "base/debug/stack_trace.h" |
-#import "base/logging.h" |
+#include "base/logging.h" |
#include "base/mac/call_with_eh_frame.h" |
-#import "base/mac/scoped_nsobject.h" |
-#import "base/mac/scoped_objc_class_swizzler.h" |
-#include "base/macros.h" |
-#import "base/metrics/histogram_macros.h" |
#include "base/strings/stringprintf.h" |
-#import "base/strings/sys_string_conversions.h" |
+#include "base/strings/sys_string_conversions.h" |
#import "chrome/browser/app_controller_mac.h" |
-#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
+#import "chrome/browser/mac/exception_processor.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/crash_keys.h" |
#import "components/crash/core/common/objc_zombie.h" |
#include "content/public/browser/browser_accessibility_state.h" |
-#include "content/public/browser/render_view_host.h" |
-#include "content/public/browser/web_contents.h" |
namespace chrome_browser_application_mac { |
-// Maximum number of known named exceptions we'll support. There is |
-// no central registration, but I only find about 75 possibilities in |
-// the system frameworks, and many of them are probably not |
-// interesting to track in aggregate (those relating to distributed |
-// objects, for instance). |
-const size_t kKnownNSExceptionCount = 25; |
- |
-const size_t kUnknownNSException = kKnownNSExceptionCount; |
- |
-size_t BinForException(NSException* exception) { |
- // A list of common known exceptions. The list position will |
- // determine where they live in the histogram, so never move them |
- // around, only add to the end. |
- static NSString* const kKnownNSExceptionNames[] = { |
- // Grab-bag exception, not very common. CFArray (or other |
- // container) mutated while being enumerated is one case seen in |
- // production. |
- NSGenericException, |
- |
- // Out-of-range on NSString or NSArray. Quite common. |
- NSRangeException, |
- |
- // Invalid arg to method, unrecognized selector. Quite common. |
- NSInvalidArgumentException, |
- |
- // malloc() returned null in object creation, I think. Turns out |
- // to be very uncommon in production, because of the OOM killer. |
- NSMallocException, |
- |
- // This contains things like windowserver errors, trying to draw |
- // views which aren't in windows, unable to read nib files. By |
- // far the most common exception seen on the crash server. |
- NSInternalInconsistencyException, |
- |
- nil |
- }; |
- |
- // Make sure our array hasn't outgrown our abilities to track it. |
- DCHECK_LE(arraysize(kKnownNSExceptionNames), kKnownNSExceptionCount); |
- |
- NSString* name = [exception name]; |
- for (int i = 0; kKnownNSExceptionNames[i]; ++i) { |
- if (name == kKnownNSExceptionNames[i]) { |
- return i; |
- } |
- } |
- return kUnknownNSException; |
-} |
- |
-void RecordExceptionWithUma(NSException* exception) { |
- UMA_HISTOGRAM_ENUMERATION("OSX.NSException", |
- BinForException(exception), kUnknownNSException); |
-} |
- |
-namespace { |
- |
-objc_exception_preprocessor g_next_preprocessor = nullptr; |
- |
-id ExceptionPreprocessor(id exception) { |
- static bool seen_first_exception = false; |
- |
- RecordExceptionWithUma(exception); |
- |
- const char* const kExceptionKey = |
- seen_first_exception ? crash_keys::mac::kLastNSException |
- : crash_keys::mac::kFirstNSException; |
- NSString* value = [NSString stringWithFormat:@"%@ reason %@", |
- [exception name], [exception reason]]; |
- base::debug::SetCrashKeyValue(kExceptionKey, [value UTF8String]); |
- |
- const char* const kExceptionTraceKey = |
- seen_first_exception ? crash_keys::mac::kLastNSExceptionTrace |
- : crash_keys::mac::kFirstNSExceptionTrace; |
- // This exception preprocessor runs prior to the one in libobjc, which sets |
- // the -[NSException callStackReturnAddresses]. |
- base::debug::SetCrashKeyToStackTrace(kExceptionTraceKey, |
- base::debug::StackTrace()); |
- |
- seen_first_exception = true; |
- |
- // Forward to the original version. |
- if (g_next_preprocessor) |
- return g_next_preprocessor(exception); |
- return exception; |
-} |
- |
-} // namespace |
- |
void RegisterBrowserCrApp() { |
[BrowserCrApplication sharedApplication]; |
}; |
@@ -145,11 +47,7 @@ void CancelTerminate() { |
// the most recent 10,000 of them on the treadmill. |
ObjcEvilDoers::ZombieEnable(true, 10000); |
- if (!chrome_browser_application_mac::g_next_preprocessor) { |
- chrome_browser_application_mac::g_next_preprocessor = |
- objc_setExceptionPreprocessor( |
- &chrome_browser_application_mac::ExceptionPreprocessor); |
- } |
+ chrome::InstallObjcExceptionPreprocessor(); |
} |
- (id)init { |
@@ -339,7 +237,11 @@ void CancelTerminate() { |
aTarget); |
base::debug::ScopedCrashKey key(crash_keys::mac::kSendAction, value); |
- return [super sendAction:anAction to:aTarget from:sender]; |
+ __block BOOL rv; |
+ base::mac::CallWithEHFrame(^{ |
+ rv = [super sendAction:anAction to:aTarget from:sender]; |
+ }); |
+ return rv; |
} |
- (BOOL)isHandlingSendEvent { |