tor-browser

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

make-debugger.js (4494B)


      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 "use strict";
      6 
      7 const EventEmitter = require("resource://devtools/shared/event-emitter.js");
      8 const Debugger = require("Debugger");
      9 
     10 const {
     11  reportException,
     12 } = require("resource://devtools/shared/DevToolsUtils.js");
     13 
     14 /**
     15 * Multiple actors that use a |Debugger| instance come in a few versions, each
     16 * with a different set of debuggees. One version for content tabs (globals
     17 * within a tab), one version for chrome debugging (all globals), and sometimes
     18 * a third version for addon debugging (chrome globals the addon is loaded in
     19 * and content globals the addon injects scripts into). The |makeDebugger|
     20 * function helps us avoid repeating the logic for finding and maintaining the
     21 * correct set of globals for a given |Debugger| instance across each version of
     22 * all of our actors.
     23 *
     24 * The |makeDebugger| function expects a single object parameter with the
     25 * following properties:
     26 *
     27 * @param Function findDebuggees
     28 *        Called with one argument: a |Debugger| instance. This function should
     29 *        return an iterable of globals to be added to the |Debugger|
     30 *        instance. The globals are the actual global objects and aren't wrapped
     31 *        in in a |Debugger.Object|.
     32 *
     33 * @param Function shouldAddNewGlobalAsDebuggee
     34 *        Called with one argument: a |Debugger.Object| wrapping a global
     35 *        object. This function must return |true| if the global object should
     36 *        be added as debuggee, and |false| otherwise.
     37 *
     38 * @returns Debugger
     39 *          Returns a |Debugger| instance that can manage its set of debuggee
     40 *          globals itself and is decorated with the |EventEmitter| class.
     41 *
     42 *          Existing |Debugger| properties set on the returned |Debugger|
     43 *          instance:
     44 *
     45 *            - onNewGlobalObject: The |Debugger| will automatically add new
     46 *              globals as debuggees if calling |shouldAddNewGlobalAsDebuggee|
     47 *              with the global returns true.
     48 *
     49 *            - uncaughtExceptionHook: The |Debugger| already has an error
     50 *              reporter attached to |uncaughtExceptionHook|, so if any
     51 *              |Debugger| hooks fail, the error will be reported.
     52 *
     53 *          New properties set on the returned |Debugger| instance:
     54 *
     55 *            - addDebuggees: A function which takes no arguments. It adds all
     56 *              current globals that should be debuggees (as determined by
     57 *              |findDebuggees|) to the |Debugger| instance.
     58 */
     59 module.exports = function makeDebugger({
     60  findDebuggees,
     61  shouldAddNewGlobalAsDebuggee,
     62 } = {}) {
     63  const dbg = new Debugger();
     64  EventEmitter.decorate(dbg);
     65 
     66  // By default, we disable asm.js and WASM debugging because of performance reason.
     67  // Enabling asm.js debugging (allowUnobservedAsmJS=false) will make asm.js fallback to JS compiler
     68  // and be debugging as a regular JS script.
     69  dbg.allowUnobservedAsmJS = true;
     70  // Enabling WASM debugging (allowUnobservedWasm=false) will make the engine compile WASM scripts
     71  // into different machine code with debugging instructions. This significantly increase the memory usage of it.
     72  dbg.allowUnobservedWasm = true;
     73 
     74  dbg.uncaughtExceptionHook = reportDebuggerHookException;
     75 
     76  const onNewGlobalObject = function (global) {
     77    if (shouldAddNewGlobalAsDebuggee(global)) {
     78      safeAddDebuggee(this, global);
     79    }
     80  };
     81 
     82  dbg.onNewGlobalObject = onNewGlobalObject;
     83  dbg.addDebuggees = function () {
     84    for (const global of findDebuggees(this)) {
     85      safeAddDebuggee(this, global);
     86    }
     87  };
     88 
     89  dbg.disable = function () {
     90    dbg.removeAllDebuggees();
     91    dbg.onNewGlobalObject = undefined;
     92  };
     93 
     94  dbg.enable = function () {
     95    dbg.addDebuggees();
     96    dbg.onNewGlobalObject = onNewGlobalObject;
     97  };
     98  dbg.findDebuggees = function (includeAllSameProcessGlobals) {
     99    return findDebuggees(dbg, includeAllSameProcessGlobals);
    100  };
    101 
    102  return dbg;
    103 };
    104 
    105 const reportDebuggerHookException = e => reportException("DBG-SERVER", e);
    106 
    107 /**
    108 * Add |global| as a debuggee to |dbg|, handling error cases.
    109 */
    110 function safeAddDebuggee(dbg, global) {
    111  let globalDO;
    112  try {
    113    globalDO = dbg.addDebuggee(global);
    114  } catch (e) {
    115    // Ignoring attempt to add the debugger's compartment as a debuggee.
    116    return;
    117  }
    118 
    119  if (dbg.onNewDebuggee) {
    120    dbg.onNewDebuggee(globalDO);
    121  }
    122 }