Refactor crash reporter to be more cross-platform friendly.

This commit is contained in:
Cheng Zhao 2013-11-14 13:33:09 +08:00
parent 801a19504a
commit 9007a45051
8 changed files with 171 additions and 113 deletions

View file

@ -140,7 +140,9 @@
'common/api/atom_extensions.h',
'common/api/object_life_monitor.cc',
'common/api/object_life_monitor.h',
'common/crash_reporter/crash_reporter.cc',
'common/crash_reporter/crash_reporter.h',
'common/crash_reporter/crash_reporter_mac.h',
'common/crash_reporter/crash_reporter_mac.mm',
'common/crash_reporter/crash_reporter_win.cc',
'common/draggable_region.cc',

View file

@ -14,36 +14,22 @@ namespace atom {
namespace api {
// static
v8::Handle<v8::Value> CrashReporter::SetProductName(const v8::Arguments& args) {
crash_reporter::CrashReporter::SetProductName(FromV8Value(args[0]));
return v8::Undefined();
}
v8::Handle<v8::Value> CrashReporter::Start(const v8::Arguments& args) {
std::string product_name, company_name, submit_url;
bool auto_submit, skip_system;
if (!FromV8Arguments(args, &product_name, &company_name, &submit_url,
&auto_submit, &skip_system))
return node::ThrowTypeError("Bad argument");
// static
v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments& args) {
crash_reporter::CrashReporter::SetCompanyName(FromV8Value(args[0]));
return v8::Undefined();
}
crash_reporter::CrashReporter::GetInstance()->Start(
product_name, company_name, submit_url, auto_submit, skip_system);
// static
v8::Handle<v8::Value> CrashReporter::SetSubmissionURL(
const v8::Arguments& args) {
crash_reporter::CrashReporter::SetSubmissionURL(FromV8Value(args[0]));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> CrashReporter::SetAutoSubmit(const v8::Arguments& args) {
crash_reporter::CrashReporter::SetAutoSubmit(FromV8Value(args[0]));
return v8::Undefined();
}
// static
void CrashReporter::Initialize(v8::Handle<v8::Object> target) {
node::SetMethod(target, "setProductName", SetProductName);
node::SetMethod(target, "setCompanyName", SetCompanyName);
node::SetMethod(target, "setSubmissionUrl", SetSubmissionURL);
node::SetMethod(target, "setAutoSubmit", SetAutoSubmit);
node::SetMethod(target, "start", Start);
}
} // namespace api

View file

@ -17,10 +17,7 @@ class CrashReporter {
static void Initialize(v8::Handle<v8::Object> target);
private:
static v8::Handle<v8::Value> SetProductName(const v8::Arguments &args);
static v8::Handle<v8::Value> SetCompanyName(const v8::Arguments &args);
static v8::Handle<v8::Value> SetSubmissionURL(const v8::Arguments &args);
static v8::Handle<v8::Value> SetAutoSubmit(const v8::Arguments &args);
static v8::Handle<v8::Value> Start(const v8::Arguments& args);
DISALLOW_IMPLICIT_CONSTRUCTORS(CrashReporter);
};

View file

@ -1 +1,15 @@
module.exports = process.atomBinding 'crash_reporter'
binding = process.atomBinding 'crash_reporter'
class CrashReporter
start: (options) ->
{productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler} = options
productName ?= 'Atom-Shell'
companyName ?= 'GitHub, Inc'
submitUrl ?= 'http://54.249.141.25'
autoSubmit ?= true
ignoreSystemCrashHandler ?= false
binding.start productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler
module.exports = new CrashReporter

View file

@ -0,0 +1,45 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "common/crash_reporter/crash_reporter.h"
#include "base/command_line.h"
#include "browser/browser.h"
#include "common/atom_version.h"
#include "content/public/common/content_switches.h"
namespace crash_reporter {
CrashReporter::CrashReporter() {
const CommandLine& command = *CommandLine::ForCurrentProcess();
std::string type = command.GetSwitchValueASCII(switches::kProcessType);
is_browser_ = type.empty();
}
CrashReporter::~CrashReporter() {
}
void CrashReporter::Start(std::string product_name,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler) {
std::string version;
if (is_browser_) {
// Use application's version for crashes in browser.
version = atom::Browser::Get()->GetVersion();
} else {
// Just use atom-shell's version in renderer, since we can not get
// application's version here.
version = ATOM_VERSION_STRING;
// Append "Renderer" for the renderer.
product_name += " Renderer";
}
InitBreakpad(product_name, version, company_name, submit_url, auto_submit,
skip_system_crash_handler);
}
} // namespace crash_reporter

View file

@ -13,13 +13,29 @@ namespace crash_reporter {
class CrashReporter {
public:
static void SetProductName(const std::string& name);
static void SetCompanyName(const std::string& name);
static void SetSubmissionURL(const std::string& url);
static void SetAutoSubmit(bool yes);
static CrashReporter* GetInstance();
void Start(std::string product_name,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler);
protected:
CrashReporter();
virtual ~CrashReporter();
virtual void InitBreakpad(const std::string& product_name,
const std::string& version,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler) = 0;
bool is_browser_;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(CrashReporter);
DISALLOW_COPY_AND_ASSIGN(CrashReporter);
};
} // namespace crash_reporter

View file

@ -0,0 +1,40 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_
#define ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_
#include "base/compiler_specific.h"
#include "common/crash_reporter/crash_reporter.h"
#import "vendor/breakpad/src/client/mac/Framework/Breakpad.h"
template <typename T> struct DefaultSingletonTraits;
namespace crash_reporter {
class CrashReporterMac : public CrashReporter {
public:
static CrashReporterMac* GetInstance();
virtual void InitBreakpad(const std::string& product_name,
const std::string& version,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler) OVERRIDE;
private:
friend struct DefaultSingletonTraits<CrashReporterMac>;
CrashReporterMac();
virtual ~CrashReporterMac();
BreakpadRef breakpad_;
DISALLOW_COPY_AND_ASSIGN(CrashReporterMac);
};
} // namespace crash_reporter
#endif // ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_

View file

@ -2,104 +2,62 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "common/crash_reporter/crash_reporter.h"
#include "common/crash_reporter/crash_reporter_mac.h"
#include "browser/browser.h"
#include "base/mac/mac_util.h"
#include "base/memory/singleton.h"
#include "base/strings/sys_string_conversions.h"
#include "common/atom_version.h"
#import "vendor/breakpad/src/client/apple/Framework/BreakpadDefines.h"
#import "vendor/breakpad/src/client/mac/Framework/Breakpad.h"
namespace crash_reporter {
namespace {
CrashReporterMac::CrashReporterMac()
: breakpad_(NULL) {
}
class ScopedCrashReporter {
public:
ScopedCrashReporter() : is_browser_(!base::mac::IsBackgroundOnlyProcess()) {
NSMutableDictionary* parameters =
[NSMutableDictionary dictionaryWithCapacity:4];
[parameters setValue:@"GitHub, Inc" forKey:@BREAKPAD_VENDOR];
CrashReporterMac::~CrashReporterMac() {
if (breakpad_ != NULL)
BreakpadRelease(breakpad_);
}
if (is_browser_) {
[parameters setValue:@"Atom-Shell" forKey:@BREAKPAD_PRODUCT];
// Use application's version for crashes in browser.
std::string version = atom::Browser::Get()->GetVersion();
[parameters setValue:base::SysUTF8ToNSString(version)
forKey:@BREAKPAD_VERSION];
} else {
[parameters setValue:@"Atom-Shell Renderer" forKey:@BREAKPAD_PRODUCT];
[parameters setValue:@ATOM_VERSION_STRING forKey:@BREAKPAD_VERSION];
}
void CrashReporterMac::InitBreakpad(const std::string& product_name,
const std::string& version,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler) {
if (breakpad_ != NULL)
BreakpadRelease(breakpad_);
// Report all crashes (important for testing the crash reporter).
[parameters setValue:@"0" forKey:@BREAKPAD_REPORT_INTERVAL];
NSMutableDictionary* parameters =
[NSMutableDictionary dictionaryWithCapacity:4];
// Let the crash reporter log everything in Console.app.
[parameters setValue:@"NO" forKey:@BREAKPAD_SEND_AND_EXIT];
[parameters setValue:base::SysUTF8ToNSString(product_name)
forKey:@BREAKPAD_PRODUCT];
[parameters setValue:base::SysUTF8ToNSString(version)
forKey:@BREAKPAD_VERSION];
[parameters setValue:base::SysUTF8ToNSString(company_name)
forKey:@BREAKPAD_VENDOR];
[parameters setValue:base::SysUTF8ToNSString(submit_url)
forKey:@BREAKPAD_URL];
[parameters setValue:(auto_submit ? @"YES" : @"NO")
forKey:@BREAKPAD_SKIP_CONFIRM];
[parameters setValue:(skip_system_crash_handler ? @"YES" : @"NO")
forKey:@BREAKPAD_SEND_AND_EXIT];
// Send the report by default.
[parameters setValue:@"YES" forKey:@BREAKPAD_SKIP_CONFIRM];
// Report all crashes (important for testing the crash reporter).
[parameters setValue:@"0" forKey:@BREAKPAD_REPORT_INTERVAL];
// Use my server as /dev/null if not specified.
[parameters setValue:@"http://54.249.141.255" forKey:@BREAKPAD_URL];
breakpad_ = BreakpadCreate(parameters);
}
~ScopedCrashReporter() { if (breakpad_) BreakpadRelease(breakpad_); }
bool is_browser() const { return is_browser_; }
void SetKey(const std::string& key, const std::string& value) {
BreakpadSetKeyValue(breakpad_,
base::SysUTF8ToNSString(key),
base::SysUTF8ToNSString(value));
}
static ScopedCrashReporter* Get() {
if (g_scoped_crash_reporter_ == NULL)
g_scoped_crash_reporter_ = new ScopedCrashReporter();
return g_scoped_crash_reporter_;
}
private:
BreakpadRef breakpad_;
bool is_browser_;
static ScopedCrashReporter* g_scoped_crash_reporter_;
DISALLOW_COPY_AND_ASSIGN(ScopedCrashReporter);
};
ScopedCrashReporter* ScopedCrashReporter::g_scoped_crash_reporter_ = NULL;
} // namespace
// static
void CrashReporter::SetProductName(const std::string& name) {
ScopedCrashReporter* reporter = ScopedCrashReporter::Get();
if (reporter->is_browser())
ScopedCrashReporter::Get()->SetKey(BREAKPAD_PRODUCT_DISPLAY, name);
else
ScopedCrashReporter::Get()->SetKey(BREAKPAD_PRODUCT_DISPLAY,
name + " Renderer");
breakpad_ = BreakpadCreate(parameters);
}
// static
void CrashReporter::SetCompanyName(const std::string& name) {
ScopedCrashReporter::Get()->SetKey(BREAKPAD_VENDOR, name);
CrashReporterMac* CrashReporterMac::GetInstance() {
return Singleton<CrashReporterMac>::get();
}
// static
void CrashReporter::SetSubmissionURL(const std::string& url) {
ScopedCrashReporter::Get()->SetKey(BREAKPAD_URL, url);
}
// static
void CrashReporter::SetAutoSubmit(bool yes) {
ScopedCrashReporter::Get()->SetKey(BREAKPAD_SKIP_CONFIRM, yes ? "YES" : "NO");
CrashReporter* CrashReporter::GetInstance() {
return CrashReporterMac::GetInstance();
}
} // namespace crash_reporter