tor-browser

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

ChildCrashHandler.sys.mjs (3635B)


      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 file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs";
      6 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
      7 
      8 const lazy = {};
      9 
     10 ChromeUtils.defineESModuleGetters(lazy, {
     11  EventDispatcher: "resource://gre/modules/Messaging.sys.mjs",
     12 });
     13 
     14 const { debug, warn } = GeckoViewUtils.initLogging("ChildCrashHandler");
     15 
     16 function getDir(name) {
     17  const uAppDataPath = Services.dirsvc.get("UAppData", Ci.nsIFile).path;
     18  return PathUtils.join(uAppDataPath, "Crash Reports", name);
     19 }
     20 
     21 var getPendingDir = function () {
     22  return getDir("pending");
     23 };
     24 
     25 var getPendingMinidump = function (id) {
     26  const pendingDir = getPendingDir();
     27 
     28  return [".dmp", ".extra"].map(suffix => {
     29    return PathUtils.join(pendingDir, `${id}${suffix}`);
     30  });
     31 };
     32 
     33 export var crashPullCallback = function (matches, requestedByDevs) {
     34  lazy.EventDispatcher.instance.sendRequest({
     35    type: "GeckoView:RemoteSettingsCrashPull",
     36    crashIDs: matches.map(id => PathUtils.join(getPendingDir(), `${id}.dmp`)),
     37  });
     38 };
     39 
     40 export var ChildCrashHandler = {
     41  // Map a child ID to a remote type.
     42  childMap: new Map(),
     43 
     44  // The event listener for this is hooked up in GeckoViewStartup.sys.mjs
     45  observe(aSubject, aTopic, aData) {
     46    const childID = aData;
     47 
     48    switch (aTopic) {
     49      case "process-type-set":
     50      // Intentional fall-through
     51      case "ipc:content-created": {
     52        const pp = aSubject.QueryInterface(Ci.nsIDOMProcessParent);
     53        this.childMap.set(childID, pp.remoteType);
     54        break;
     55      }
     56 
     57      case "ipc:content-shutdown":
     58      // Intentional fall-through
     59      case "compositor:process-aborted": {
     60        aSubject.QueryInterface(Ci.nsIPropertyBag2);
     61 
     62        const disableReporting = Services.env.get(
     63          "MOZ_CRASHREPORTER_NO_REPORT"
     64        );
     65 
     66        if (
     67          !aSubject.get("abnormal") ||
     68          !AppConstants.MOZ_CRASHREPORTER ||
     69          disableReporting
     70        ) {
     71          return;
     72        }
     73 
     74        // If dumpID is empty the process was likely killed by the system and
     75        // we therefore do not want to report the crash. This includes most
     76        // "expected" extensions process crashes on Android.
     77        const dumpID = aSubject.get("dumpID");
     78        if (!dumpID) {
     79          return;
     80        }
     81 
     82        debug`Notifying child process crash, dump ID ${dumpID}`;
     83        const [minidumpPath, extrasPath] = getPendingMinidump(dumpID);
     84 
     85        let remoteType = this.childMap.get(childID);
     86        this.childMap.delete(childID);
     87 
     88        if (remoteType?.length) {
     89          // Only send the remote type prefix since everything after a "=" is
     90          // dynamic, and used to control the process pool to use.
     91          remoteType = remoteType.split("=")[0];
     92        }
     93 
     94        // Report GPU and extension process crashes as occuring in a background
     95        // process, and others as foreground.
     96        const processVisibility =
     97          aTopic === "compositor:process-aborted" || remoteType === "extension"
     98            ? "BACKGROUND_CHILD"
     99            : "FOREGROUND_CHILD";
    100 
    101        const processType = aSubject.get("processType");
    102 
    103        lazy.EventDispatcher.instance.sendRequest({
    104          type: "GeckoView:ChildCrashReport",
    105          minidumpPath,
    106          extrasPath,
    107          success: true,
    108          fatal: false,
    109          processVisibility,
    110          processType,
    111          remoteType,
    112        });
    113 
    114        break;
    115      }
    116    }
    117  },
    118 };