| Index: components/breakpad/app/breakpad_mac.mm
|
| diff --git a/components/breakpad/app/breakpad_mac.mm b/components/breakpad/app/breakpad_mac.mm
|
| deleted file mode 100644
|
| index 6cb5504f33aad1df4731f89d0c8d781e4748169c..0000000000000000000000000000000000000000
|
| --- a/components/breakpad/app/breakpad_mac.mm
|
| +++ /dev/null
|
| @@ -1,279 +0,0 @@
|
| -// Copyright 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#import "components/breakpad/app/breakpad_mac.h"
|
| -
|
| -#include <CoreFoundation/CoreFoundation.h>
|
| -#import <Foundation/Foundation.h>
|
| -
|
| -#include "base/auto_reset.h"
|
| -#include "base/base_switches.h"
|
| -#import "base/basictypes.h"
|
| -#include "base/command_line.h"
|
| -#include "base/debug/crash_logging.h"
|
| -#include "base/debug/dump_without_crashing.h"
|
| -#include "base/file_util.h"
|
| -#include "base/files/file_path.h"
|
| -#import "base/logging.h"
|
| -#include "base/mac/bundle_locations.h"
|
| -#include "base/mac/mac_util.h"
|
| -#include "base/mac/scoped_cftyperef.h"
|
| -#import "base/mac/scoped_nsautorelease_pool.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "base/threading/platform_thread.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#import "breakpad/src/client/mac/Framework/Breakpad.h"
|
| -#include "components/breakpad/app/breakpad_client.h"
|
| -
|
| -namespace breakpad {
|
| -
|
| -namespace {
|
| -
|
| -BreakpadRef gBreakpadRef = NULL;
|
| -
|
| -void SetCrashKeyValue(NSString* key, NSString* value) {
|
| - // Comment repeated from header to prevent confusion:
|
| - // IMPORTANT: On OS X, the key/value pairs are sent to the crash server
|
| - // out of bounds and not recorded on disk in the minidump, this means
|
| - // that if you look at the minidump file locally you won't see them!
|
| - if (gBreakpadRef == NULL) {
|
| - return;
|
| - }
|
| -
|
| - BreakpadAddUploadParameter(gBreakpadRef, key, value);
|
| -}
|
| -
|
| -void ClearCrashKeyValue(NSString* key) {
|
| - if (gBreakpadRef == NULL) {
|
| - return;
|
| - }
|
| -
|
| - BreakpadRemoveUploadParameter(gBreakpadRef, key);
|
| -}
|
| -
|
| -void SetCrashKeyValueImpl(const base::StringPiece& key,
|
| - const base::StringPiece& value) {
|
| - SetCrashKeyValue(base::SysUTF8ToNSString(key.as_string()),
|
| - base::SysUTF8ToNSString(value.as_string()));
|
| -}
|
| -
|
| -void ClearCrashKeyValueImpl(const base::StringPiece& key) {
|
| - ClearCrashKeyValue(base::SysUTF8ToNSString(key.as_string()));
|
| -}
|
| -
|
| -bool FatalMessageHandler(int severity, const char* file, int line,
|
| - size_t message_start, const std::string& str) {
|
| - // Do not handle non-FATAL.
|
| - if (severity != logging::LOG_FATAL)
|
| - return false;
|
| -
|
| - // In case of OOM condition, this code could be reentered when
|
| - // constructing and storing the key. Using a static is not
|
| - // thread-safe, but if multiple threads are in the process of a
|
| - // fatal crash at the same time, this should work.
|
| - static bool guarded = false;
|
| - if (guarded)
|
| - return false;
|
| -
|
| - base::AutoReset<bool> guard(&guarded, true);
|
| -
|
| - // Only log last path component. This matches logging.cc.
|
| - if (file) {
|
| - const char* slash = strrchr(file, '/');
|
| - if (slash)
|
| - file = slash + 1;
|
| - }
|
| -
|
| - NSString* fatal_key = @"LOG_FATAL";
|
| - NSString* fatal_value =
|
| - [NSString stringWithFormat:@"%s:%d: %s",
|
| - file, line, str.c_str() + message_start];
|
| - SetCrashKeyValue(fatal_key, fatal_value);
|
| -
|
| - // Rather than including the code to force the crash here, allow the
|
| - // caller to do it.
|
| - return false;
|
| -}
|
| -
|
| -// BreakpadGenerateAndSendReport() does not report the current
|
| -// thread. This class can be used to spin up a thread to run it.
|
| -class DumpHelper : public base::PlatformThread::Delegate {
|
| - public:
|
| - static void DumpWithoutCrashing() {
|
| - DumpHelper dumper;
|
| - base::PlatformThreadHandle handle;
|
| - if (base::PlatformThread::Create(0, &dumper, &handle)) {
|
| - // The entire point of this is to block so that the correct
|
| - // stack is logged.
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| - base::PlatformThread::Join(handle);
|
| - }
|
| - }
|
| -
|
| - private:
|
| - DumpHelper() {}
|
| -
|
| - virtual void ThreadMain() OVERRIDE {
|
| - base::PlatformThread::SetName("CrDumpHelper");
|
| - BreakpadGenerateAndSendReport(gBreakpadRef);
|
| - }
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DumpHelper);
|
| -};
|
| -
|
| -void SIGABRTHandler(int signal) {
|
| - // The OSX abort() (link below) masks all signals for the process,
|
| - // and all except SIGABRT for the thread. SIGABRT will be masked
|
| - // when the SIGABRT is sent, which means at this point only SIGKILL
|
| - // and SIGSTOP can be delivered. Unmask others so that the code
|
| - // below crashes as desired.
|
| - //
|
| - // http://www.opensource.apple.com/source/Libc/Libc-825.26/stdlib/FreeBSD/abort.c
|
| - sigset_t mask;
|
| - sigemptyset(&mask);
|
| - sigaddset(&mask, signal);
|
| - pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
| -
|
| - // Most interesting operations are not safe in a signal handler, just crash.
|
| - char* volatile death_ptr = NULL;
|
| - *death_ptr = '!';
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -bool IsCrashReporterEnabled() {
|
| - return gBreakpadRef != NULL;
|
| -}
|
| -
|
| -// Only called for a branded build of Chrome.app.
|
| -void InitCrashReporter(const std::string& process_type) {
|
| - DCHECK(!gBreakpadRef);
|
| - base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
| -
|
| - // Check whether crash reporting should be enabled. If enterprise
|
| - // configuration management controls crash reporting, it takes precedence.
|
| - // Otherwise, check whether the user has consented to stats and crash
|
| - // reporting. The browser process can make this determination directly.
|
| - // Helper processes may not have access to the disk or to the same data as
|
| - // the browser process, so the browser passes the decision to them on the
|
| - // command line.
|
| - NSBundle* main_bundle = base::mac::FrameworkBundle();
|
| - bool is_browser = !base::mac::IsBackgroundOnlyProcess();
|
| - bool enable_breakpad = false;
|
| - CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| -
|
| - if (is_browser) {
|
| - // Since the configuration management infrastructure is possibly not
|
| - // initialized when this code runs, read the policy preference directly.
|
| - if (!GetBreakpadClient()->ReportingIsEnforcedByPolicy(&enable_breakpad)) {
|
| - // Controlled by the user. The crash reporter may be enabled by
|
| - // preference or through an environment variable, but the kDisableBreakpad
|
| - // switch overrides both.
|
| - enable_breakpad = GetBreakpadClient()->GetCollectStatsConsent() ||
|
| - GetBreakpadClient()->IsRunningUnattended();
|
| - enable_breakpad &= !command_line->HasSwitch(switches::kDisableBreakpad);
|
| - }
|
| - } else {
|
| - // This is a helper process, check the command line switch.
|
| - enable_breakpad = command_line->HasSwitch(switches::kEnableCrashReporter);
|
| - }
|
| -
|
| - if (!enable_breakpad) {
|
| - VLOG_IF(1, is_browser) << "Breakpad disabled";
|
| - return;
|
| - }
|
| -
|
| - // Tell Breakpad where crash_inspector and crash_report_sender are.
|
| - NSString* resource_path = [main_bundle resourcePath];
|
| - NSString *inspector_location =
|
| - [resource_path stringByAppendingPathComponent:@"crash_inspector"];
|
| - NSString *reporter_bundle_location =
|
| - [resource_path stringByAppendingPathComponent:@"crash_report_sender.app"];
|
| - NSString *reporter_location =
|
| - [[NSBundle bundleWithPath:reporter_bundle_location] executablePath];
|
| -
|
| - if (!inspector_location || !reporter_location) {
|
| - VLOG_IF(1, is_browser && base::mac::AmIBundled()) << "Breakpad disabled";
|
| - return;
|
| - }
|
| -
|
| - NSDictionary* info_dictionary = [main_bundle infoDictionary];
|
| - NSMutableDictionary *breakpad_config =
|
| - [[info_dictionary mutableCopy] autorelease];
|
| - [breakpad_config setObject:inspector_location
|
| - forKey:@BREAKPAD_INSPECTOR_LOCATION];
|
| - [breakpad_config setObject:reporter_location
|
| - forKey:@BREAKPAD_REPORTER_EXE_LOCATION];
|
| -
|
| - // In the main application (the browser process), crashes can be passed to
|
| - // the system's Crash Reporter. This allows the system to notify the user
|
| - // when the application crashes, and provide the user with the option to
|
| - // restart it.
|
| - if (is_browser)
|
| - [breakpad_config setObject:@"NO" forKey:@BREAKPAD_SEND_AND_EXIT];
|
| -
|
| - base::FilePath dir_crash_dumps;
|
| - GetBreakpadClient()->GetCrashDumpLocation(&dir_crash_dumps);
|
| - [breakpad_config setObject:base::SysUTF8ToNSString(dir_crash_dumps.value())
|
| - forKey:@BREAKPAD_DUMP_DIRECTORY];
|
| -
|
| - // Initialize Breakpad.
|
| - gBreakpadRef = BreakpadCreate(breakpad_config);
|
| - if (!gBreakpadRef) {
|
| - LOG_IF(ERROR, base::mac::AmIBundled()) << "Breakpad initializaiton failed";
|
| - return;
|
| - }
|
| -
|
| - // Initialize the scoped crash key system.
|
| - base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValueImpl,
|
| - &ClearCrashKeyValueImpl);
|
| - GetBreakpadClient()->RegisterCrashKeys();
|
| -
|
| - // Set Breakpad metadata values. These values are added to Info.plist during
|
| - // the branded Google Chrome.app build.
|
| - SetCrashKeyValue(@"ver", [info_dictionary objectForKey:@BREAKPAD_VERSION]);
|
| - SetCrashKeyValue(@"prod", [info_dictionary objectForKey:@BREAKPAD_PRODUCT]);
|
| - SetCrashKeyValue(@"plat", @"OS X");
|
| -
|
| - if (!is_browser) {
|
| - // Get the guid from the command line switch.
|
| - std::string client_guid =
|
| - command_line->GetSwitchValueASCII(switches::kEnableCrashReporter);
|
| - GetBreakpadClient()->SetBreakpadClientIdFromGUID(client_guid);
|
| - }
|
| -
|
| - logging::SetLogMessageHandler(&FatalMessageHandler);
|
| - base::debug::SetDumpWithoutCrashingFunction(&DumpHelper::DumpWithoutCrashing);
|
| -
|
| - // abort() sends SIGABRT, which breakpad does not intercept.
|
| - // Register a signal handler to crash in a way breakpad will
|
| - // intercept.
|
| - struct sigaction sigact;
|
| - memset(&sigact, 0, sizeof(sigact));
|
| - sigact.sa_handler = SIGABRTHandler;
|
| - CHECK(0 == sigaction(SIGABRT, &sigact, NULL));
|
| -}
|
| -
|
| -void InitCrashProcessInfo(const std::string& process_type_switch) {
|
| - if (gBreakpadRef == NULL) {
|
| - return;
|
| - }
|
| -
|
| - // Determine the process type.
|
| - NSString* process_type = @"browser";
|
| - if (!process_type_switch.empty()) {
|
| - process_type = base::SysUTF8ToNSString(process_type_switch);
|
| - }
|
| -
|
| - GetBreakpadClient()->InstallAdditionalFilters(gBreakpadRef);
|
| -
|
| - // Store process type in crash dump.
|
| - SetCrashKeyValue(@"ptype", process_type);
|
| -
|
| - NSString* pid_value =
|
| - [NSString stringWithFormat:@"%d", static_cast<unsigned int>(getpid())];
|
| - SetCrashKeyValue(@"pid", pid_value);
|
| -}
|
| -
|
| -} // namespace breakpad
|
|
|