tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CrashReporterHelper.h (3633B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef mozilla_ipc_CrashReporterHelper_h
      6 #define mozilla_ipc_CrashReporterHelper_h
      7 
      8 #include "CrashReporterHost.h"
      9 #include "mozilla/UniquePtr.h"
     10 #include "nsIAppStartup.h"
     11 #include "nsExceptionHandler.h"
     12 #include "nsICrashService.h"
     13 #include "nsPrintfCString.h"
     14 #include "nsServiceManagerUtils.h"
     15 
     16 namespace mozilla::ipc {
     17 
     18 /**
     19 * This class encapsulates the common elements of crash report handling for
     20 * toplevel protocols representing processes. To use this class, you should:
     21 *
     22 * 1. Declare a method to initialize the crash reporter in your IPDL:
     23 *    `async InitCrashReporter(NativeThreadId threadId)`
     24 *
     25 * 2. Inherit from this class with the name of your derived class as the
     26 *    type parameter. Ex: `class MyClass : public CrashReporterHelper<MyClass>`
     27 *
     28 * 3. Provide a public `PROCESS_TYPE` constant for your class. Ex:
     29 *
     30 *    ```
     31 *    public:
     32 *      static constexpr GeckoProcessType PROCESS_TYPE =
     33 *          GeckoProcessType_GMPlugin;
     34 *    ```
     35 *
     36 * 4. When your protocol actor is destroyed with a reason of `AbnormalShutdown`,
     37 *    you should call `GenerateCrashReport()`. If you need the crash
     38 *    report ID it will be copied in the second optional parameter upon
     39 *    successful crash report generation.
     40 */
     41 template <class Derived>
     42 class CrashReporterHelper {
     43 public:
     44  CrashReporterHelper() : mCrashReporter(nullptr) {}
     45  IPCResult RecvInitCrashReporter(
     46      const CrashReporter::CrashReporterInitArgs& aInitArgs) {
     47    base::ProcessId pid = static_cast<Derived*>(this)->OtherPid();
     48    mCrashReporter = MakeUnique<ipc::CrashReporterHost>(Derived::PROCESS_TYPE,
     49                                                        pid, aInitArgs);
     50    return IPC_OK();
     51  }
     52 
     53 protected:
     54  void GenerateCrashReport(nsString* aMinidumpId = nullptr) {
     55    nsAutoString minidumpId;
     56    if (!mCrashReporter) {
     57      HandleOrphanedMinidump(minidumpId);
     58    } else if (mCrashReporter->GenerateCrashReport()) {
     59      minidumpId = mCrashReporter->MinidumpID();
     60    }
     61 
     62    if (aMinidumpId) {
     63      *aMinidumpId = minidumpId;
     64    }
     65 
     66    mCrashReporter = nullptr;
     67  }
     68 
     69  void MaybeTerminateProcess() {
     70    if (PR_GetEnv("MOZ_CRASHREPORTER_SHUTDOWN")) {
     71      NS_WARNING(nsPrintfCString("Shutting down due to %s process crash.",
     72                                 XRE_GetProcessTypeString())
     73                     .get());
     74      nsCOMPtr<nsIAppStartup> appService =
     75          do_GetService("@mozilla.org/toolkit/app-startup;1");
     76      if (appService) {
     77        bool userAllowedQuit = true;
     78        appService->Quit(nsIAppStartup::eForceQuit, 1, &userAllowedQuit);
     79      }
     80    }
     81  }
     82 
     83 private:
     84  void HandleOrphanedMinidump(nsString& aMinidumpId) {
     85    base::ProcessId pid = static_cast<Derived*>(this)->OtherPid();
     86    if (CrashReporter::FinalizeOrphanedMinidump(pid, Derived::PROCESS_TYPE,
     87                                                &aMinidumpId)) {
     88      CrashReporterHost::RecordCrash(Derived::PROCESS_TYPE,
     89                                     nsICrashService::CRASH_TYPE_CRASH,
     90                                     aMinidumpId);
     91    } else {
     92      NS_WARNING(nsPrintfCString("child process pid = %" PRIPID
     93                                 " crashed without leaving a minidump behind",
     94                                 pid)
     95                     .get());
     96    }
     97  }
     98 
     99 protected:
    100  UniquePtr<ipc::CrashReporterHost> mCrashReporter;
    101 };
    102 
    103 }  // namespace mozilla::ipc
    104 
    105 #endif  // mozilla_ipc_CrashReporterHelper_h