summaryrefslogtreecommitdiffstats
path: root/mobile/android/modules/geckoview/ContentCrashHandler.jsm
blob: 873c773dc0e8cb657b820939a817764dab666762 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = ["ContentCrashHandler"];

const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);
const { GeckoViewUtils } = ChromeUtils.import(
  "resource://gre/modules/GeckoViewUtils.jsm"
);

XPCOMUtils.defineLazyModuleGetters(this, {
  AppConstants: "resource://gre/modules/AppConstants.jsm",
  EventDispatcher: "resource://gre/modules/Messaging.jsm",
  Services: "resource://gre/modules/Services.jsm",
});

ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");

const { debug, warn } = GeckoViewUtils.initLogging("ContentCrashHandler");

function getDir(name) {
  const uAppDataPath = Services.dirsvc.get("UAppData", Ci.nsIFile).path;
  return OS.Path.join(uAppDataPath, "Crash Reports", name);
}

function getPendingMinidump(id) {
  const pendingDir = getDir("pending");

  return [".dmp", ".extra"].map(suffix => {
    return OS.Path.join(pendingDir, `${id}${suffix}`);
  });
}

var ContentCrashHandler = {
  // The event listener for this is hooked up in GeckoViewStartup.jsm
  observe(aSubject, aTopic, aData) {
    aSubject.QueryInterface(Ci.nsIPropertyBag2);

    const disableReporting = Cc["@mozilla.org/process/environment;1"]
      .getService(Ci.nsIEnvironment)
      .get("MOZ_CRASHREPORTER_NO_REPORT");

    if (
      !aSubject.get("abnormal") ||
      !AppConstants.MOZ_CRASHREPORTER ||
      disableReporting
    ) {
      return;
    }

    const dumpID = aSubject.get("dumpID");
    if (!dumpID) {
      Services.telemetry
        .getHistogramById("FX_CONTENT_CRASH_DUMP_UNAVAILABLE")
        .add(1);
      return;
    }

    debug`Notifying content process crash, dump ID ${dumpID}`;
    const [minidumpPath, extrasPath] = getPendingMinidump(dumpID);

    EventDispatcher.instance.sendRequest({
      type: "GeckoView:ContentCrashReport",
      minidumpPath,
      extrasPath,
      success: true,
      fatal: false,
    });
  },
};