js/src/doc/Debugger/Debugger-API.md

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 # The `Debugger` Interface
     3 Mozilla's JavaScript engine, SpiderMonkey, provides a debugging interface
     4 named `Debugger` which lets JavaScript code observe and manipulate the
     5 execution of other JavaScript code. Both Firefox's built-in developer tools
     6 and the Firebug add-on use `Debugger` to implement their JavaScript
     7 debuggers. However, `Debugger` is quite general, and can be used to
     8 implement other kinds of tools like tracers, coverage analysis,
     9 patch-and-continue, and so on.
    11 `Debugger` has three essential qualities:
    13 - It is a *source level* interface: it operates in terms of the JavaScript
    14   language, not machine language. It operates on JavaScript objects, stack
    15   frames, environments, and code, and presents a consistent interface
    16   regardless of whether the debuggee is interpreted, compiled, or
    17   optimized. If you have a strong command of the JavaScript language, you
    18   should have all the background you need to use `Debugger` successfully,
    19   even if you have never looked into the language's implementation.
    21 - It is for use *by JavaScript code*. JavaScript is both the debuggee
    22   language and the tool implementation language, so the qualities that make
    23   JavaScript effective on the web can be brought to bear in crafting tools
    24   for developers. As is expected of JavaScript APIs, `Debugger` is a
    25   *sound* interface: using (or even misusing) `Debugger` should never cause
    26   Gecko to crash. Errors throw proper JavaScript exceptions.
    28 - It is an *intra-thread* debugging API. Both the debuggee and the code
    29   using `Debugger` to observe it must run in the same thread. Cross-thread,
    30   cross-process, and cross-device tools must use `Debugger` to observe the
    31   debuggee from within the same thread, and then handle any needed
    32   communication themselves. (Firefox's builtin tools have a
    33   [protocol][protocol] defined for this purpose.)
    35 In Gecko, the `Debugger` API is available to chrome code only. By design,
    36 it ought not to introduce security holes, so in principle it could be made
    37 available to content as well; but it is hard to justify the security risks
    38 of the additional attack surface.
    41 ## Debugger Instances and Shadow Objects
    43 `Debugger` reflects every aspect of the debuggee's state as a JavaScript
    44 value&mdash;not just actual JavaScript values like objects and primitives,
    45 but also stack frames, environments, scripts, and compilation units, which
    46 are not normally accessible as objects in their own right.
    48 Here is a JavaScript program in the process of running a timer callback function:
    50 ![A running JavaScript program and its Debugger shadows][img-shadows]
    52 This diagram shows the various types of shadow objects that make up the
    53 Debugger API (which all follow some [general conventions][conventions]):
    55 - A [`Debugger.Object`][object] represents a debuggee object, offering a
    56   reflection-oriented API that protects the debugger from accidentally
    57   invoking getters, setters, proxy traps, and so on.
    59 - A [`Debugger.Script`][script] represents a block of JavaScript
    60   code&mdash;either a function body or a top-level script. Given a
    61   `Debugger.Script`, one can set breakpoints, translate between source
    62   positions and bytecode offsets (a deviation from the "source level"
    63   design principle), and find other static characteristics of the code.
    65 - A [`Debugger.Frame`][frame] represents a running stack frame. You can use
    66   these to walk the stack and find each frame's script and environment. You
    67   can also set `onStep` and `onPop` handlers on frames.
    69 - A [`Debugger.Environment`][environment] represents an environment,
    70   associating variable names with storage locations. Environments may
    71   belong to a running stack frame, captured by a function closure, or
    72   reflect some global object's properties as variables.
    74 The [`Debugger`][debugger-object] instance itself is not really a shadow of
    75 anything in the debuggee; rather, it maintains the set of global objects
    76 which are to be considered debuggees. A `Debugger` observes only execution
    77 taking place in the scope of these global objects. You can set functions to
    78 be called when new stack frames are pushed; when new code is loaded; and so
    79 on.
    81 Omitted from this picture are [`Debugger.Source`][source] instances, which
    82 represent JavaScript compilation units. A `Debugger.Source` can furnish a
    83 full copy of its source code, and explain how the code entered the system,
    84 whether via a call to `eval`, a `<script>` element, or otherwise. A
    85 `Debugger.Script` points to the `Debugger.Source` from which it is derived.
    87 All these types follow some [general conventions][conventions], which you
    88 should look through before drilling down into any particular type's
    89 specification.
    91 All shadow objects are unique per `Debugger` and per referent. For a given
    92 `Debugger`, there is exactly one `Debugger.Object` that refers to a
    93 particular debuggee object; exactly one `Debugger.Frame` for a particular
    94 stack frame; and so on. Thus, a tool can store metadata about a shadow's
    95 referent as a property on the shadow itself, and count on finding that
    96 metadata again if it comes across the same referent. And since shadows are
    97 per-`Debugger`, tools can do so without worrying about interfering with
    98 other tools that use their own `Debugger` instances.
   101 ## Example
   103 You can try out `Debugger` yourself in Firefox's Scratchpad.
   105 1)  Visit the URL `about:config`, and set the `devtools.chrome.enabled`
   106     preference to `true`:
   108     ![Setting the 'devtools.chrome.enabled' preference][img-chrome-pref]
   110 2)  Save the following HTML text to a file, and visit the file in your
   111     browser:
   113         <div onclick="var x = 'snoo'; debugger;">Click me!</div>
   115 3)  Open a developer Scratchpad (Menu button > Developer > Scratchpad), and
   116     select "Browser" from the "Environment" menu. (This menu will not be
   117     present unless you have changed the preference as explained above.)
   119     ![Selecting the 'browser' context in the Scratchpad][img-scratchpad-browser]
   121 4)  Enter the following code in the Scratchpad:
   123         // This simply defines 'Debugger' in this Scratchpad;
   124         // it doesn't actually start debugging anything.
   125         Cu.import("resource://gre/modules/jsdebugger.jsm");
   126         addDebuggerToGlobal(window);
   128         // Create a 'Debugger' instance.
   129         var dbg = new Debugger;
   131         // Get the current tab's content window, and make it a debuggee.
   132         var w = gBrowser.selectedBrowser.contentWindow.wrappedJSObject;
   133         dbg.addDebuggee(w);
   135         // When the debuggee executes a 'debugger' statement, evaluate
   136         // the expression 'x' in that stack frame, and show its value.
   137         dbg.onDebuggerStatement = function (frame) {
   138             alert('hit debugger statement; x = ' + frame.eval('x').return);
   139         }
   141 5)  In the Scratchpad, ensure that no text is selected, and press the "Run"
   142     button.
   144 6)  Now, click on the text that says "Click me!" in the web page. This runs
   145     the `div` element's `onclick` handler. When control reaches the
   146     `debugger;` statement, `Debugger` calls your callback function, passing
   147     a `Debugger.Frame` instance. Your callback function evaluates the
   148     expression `x` in the given stack frame, and displays the alert:
   150     ![The Debugger callback displaying an alert][img-example-alert]
   152 7)  Press "Run" in the Scratchpad again. Now, clicking on the "Click me!"
   153     text causes *two* alerts to show&mdash;one for each `Debugger`
   154     instance.
   156     Multiple `Debugger` instances can observe the same debuggee. Re-running
   157     the code in the Scratchpad created a fresh `Debugger` instance, added
   158     the same web page as its debuggee, and then registered a fresh
   159     `debugger;` statement handler with the new instance. When you clicked
   160     on the `div` element, both of them ran. This shows how any number of
   161     `Debugger`-based tools can observe a single web page
   162     simultaneously&mdash;although, since the order in which their handlers
   163     run is not specified, such tools should probably only observe, and not
   164     influence, the debuggee's behavior.
   166 8)  Close the web page and the Scratchpad.
   168     Since both the Scratchpad's global object and the debuggee window are
   169     now gone, the `Debugger` instances will be garbage collected, since
   170     they can no longer have any visible effect on Firefox's behavior. The
   171     `Debugger` API tries to interact with garbage collection as
   172     transparently as possible; for example, if both a `Debugger.Object`
   173     instance and its referent are not reachable, they will both be
   174     collected, even while the `Debugger` instance to which the shadow
   175     belonged continues to exist.
   178 ## Gecko-specific features
   180 While the `Debugger` core API deals only with concepts common to any
   181 JavaScript implementation, it also includes some Gecko-specific features:
   183 - [Global tracking][global] supports debugging all the code running in a
   184   Gecko instance at once&mdash;the 'chrome debugging' model.
   185 - [Object wrapper][wrapper] functions help manipulate object references
   186   that cross privilege boundaries.

mercurial