Refactor crash reporter to be more cross-platform friendly.
authorCheng Zhao <zcbenz@gmail.com>
Thu, 14 Nov 2013 05:33:09 +0000 (13:33 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 14 Nov 2013 05:33:09 +0000 (13:33 +0800)
atom.gyp
common/api/atom_api_crash_reporter.cc
common/api/atom_api_crash_reporter.h
common/api/lib/crash-reporter.coffee
common/crash_reporter/crash_reporter.cc [new file with mode: 0644]
common/crash_reporter/crash_reporter.h
common/crash_reporter/crash_reporter_mac.h [new file with mode: 0644]
common/crash_reporter/crash_reporter_mac.mm

index 67047a3..ee99c90 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
       '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',
index 83be95a..529ef6c 100644 (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();
-}
-
-// static
-v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments& args) {
-  crash_reporter::CrashReporter::SetCompanyName(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::SetSubmissionURL(
-    const v8::Arguments& args) {
-  crash_reporter::CrashReporter::SetSubmissionURL(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::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
index 2c8a227..f31b8b1 100644 (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);
 };
index 90f5827..09a23db 100644 (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
diff --git a/common/crash_reporter/crash_reporter.cc b/common/crash_reporter/crash_reporter.cc
new file mode 100644 (file)
index 0000000..0e23813
--- /dev/null
@@ -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
index b710037..73de0a3 100644 (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
diff --git a/common/crash_reporter/crash_reporter_mac.h b/common/crash_reporter/crash_reporter_mac.h
new file mode 100644 (file)
index 0000000..8b62699
--- /dev/null
@@ -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_
index f7d6272..970768c 100644 (file)
 // 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 {
-
-class ScopedCrashReporter {
- public:
-  ScopedCrashReporter() : is_browser_(!base::mac::IsBackgroundOnlyProcess()) {
-    NSMutableDictionary* parameters =
-        [NSMutableDictionary dictionaryWithCapacity:4];
-    [parameters setValue:@"GitHub, Inc" forKey:@BREAKPAD_VENDOR];
-
-    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];
-    }
-
-    // Report all crashes (important for testing the crash reporter).
-    [parameters setValue:@"0" forKey:@BREAKPAD_REPORT_INTERVAL];
-
-    // Let the crash reporter log everything in Console.app.
-    [parameters setValue:@"NO" forKey:@BREAKPAD_SEND_AND_EXIT];
-
-    // Send the report by default.
-    [parameters setValue:@"YES" forKey:@BREAKPAD_SKIP_CONFIRM];
-
-    // 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
+CrashReporterMac::CrashReporterMac()
+    : breakpad_(NULL) {
+}
 
-// 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");
+CrashReporterMac::~CrashReporterMac() {
+  if (breakpad_ != NULL)
+    BreakpadRelease(breakpad_);
 }
 
-// static
-void CrashReporter::SetCompanyName(const std::string& name) {
-  ScopedCrashReporter::Get()->SetKey(BREAKPAD_VENDOR, name);
+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_);
+
+  NSMutableDictionary* parameters =
+      [NSMutableDictionary dictionaryWithCapacity:4];
+
+  [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];
+
+  // Report all crashes (important for testing the crash reporter).
+  [parameters setValue:@"0" forKey:@BREAKPAD_REPORT_INTERVAL];
+
+  breakpad_ = BreakpadCreate(parameters);
 }
 
 // static
-void CrashReporter::SetSubmissionURL(const std::string& url) {
-  ScopedCrashReporter::Get()->SetKey(BREAKPAD_URL, url);
+CrashReporterMac* CrashReporterMac::GetInstance() {
+  return Singleton<CrashReporterMac>::get();
 }
 
 // static
-void CrashReporter::SetAutoSubmit(bool yes) {
-  ScopedCrashReporter::Get()->SetKey(BREAKPAD_SKIP_CONFIRM, yes ? "YES" : "NO");
+CrashReporter* CrashReporter::GetInstance() {
+  return CrashReporterMac::GetInstance();
 }
 
 }  // namespace crash_reporter