diff -r 000000000000 -r 6474c204b198 js/src/doc/Debugger/Debugger.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/src/doc/Debugger/Debugger.md Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,395 @@ +# The Debugger Object + +When called as a constructor, the `Debugger` object creates a new +`Debugger` instance. + +new Debugger([global, ...]) +: Create a debugger object, and apply its [`addDebuggee`][add] method to + each of the given global objects to add them as the initial + debuggees. + +## Accessor Properties of the Debugger Prototype Object + +A `Debugger` instance inherits the following accessor properties from +its prototype: + +`enabled` +: A boolean value indicating whether this `Debugger` instance's handlers, + breakpoints, watchpoints, and the like are currently enabled. It is an + accessor property with a getter and setter: assigning to it enables or + disables this `Debugger` instance; reading it produces true if the + instance is enabled, or false otherwise. This property is initially + `true` in a freshly created `Debugger` instance. + + This property gives debugger code a single point of control for + disentangling itself from the debuggee, regardless of what sort of + events or handlers or "points" we add to the interface. + +`uncaughtExceptionHook` +: Either `null` or a function that SpiderMonkey calls when a call to a + debug event handler, breakpoint handler, watchpoint handler, or similar + function throws some exception, which we refer to as + debugger-exception here. Exceptions thrown in the debugger are + not propagated to debuggee code; instead, SpiderMonkey calls this + function, passing debugger-exception as its sole argument and + the `Debugger` instance as the `this` value. This function should + return a [resumption value][rv], which determines how the debuggee + should continue. + + If the uncaught exception hook itself throws an exception, + uncaught-hook-exception, SpiderMonkey throws a new error object, + confess-to-debuggee-exception, to the debuggee whose message + blames the debugger, and includes textual descriptions of + uncaught-hook-exception and the original + debugger-exception. + + If `uncaughtExceptionHook`'s value is `null`, SpiderMonkey throws an + exception to the debuggee whose message blames the debugger, and + includes a textual description of debugger-exception. + + Assigning anything other than a callable value or `null` to this + property throws a `TypeError` exception. + + (This is not an ideal way to handle debugger bugs, but the hope here is + that some sort of backstop, even if imperfect, will make life easier for + debugger developers. For example, an uncaught exception hook may have + access to browser-level features like the `alert` function, which this + API's implementation does not, making it possible to present debugger + errors to the developer in a way suited to the context.) + + +## Debugger Handler Functions + +Each `Debugger` instance inherits accessor properties with which you can +store handler functions for SpiderMonkey to call when given events occur +in debuggee code. + +When one of the events described below occurs in debuggee code, the engine +pauses the debuggee and calls the corresponding debugging handler on each +`Debugger` instance that is observing the debuggee. The handler functions +receive the `Debugger` instance as their `this` value. Most handler +functions can return a [resumption value][rv] indicating how the debuggee's +execution should proceed. + +On a new `Debugger` instance, each of these properties is initially +`undefined`. Any value assigned to a debugging handler must be either a +function or `undefined`; otherwise a `TypeError` is thrown. + +Handler functions run in the same thread in which the event occurred. +They run in the compartment to which they belong, not in a debuggee +compartment. + +onNewScript(script, global) +: New code, represented by the [`Debugger.Script`][script] instance + script, has been loaded in the scope of the debuggee global + object global. global is a [`Debugger.Object`][object] + instance whose referent is the global object. + + This method's return value is ignored. + +onDebuggerStatement(frame) +: Debuggee code has executed a debugger statement in frame. + This method should return a [resumption value][rv] specifying how the + debuggee's execution should proceed. + +onEnterFrame(frame) +: The stack frame frame is about to begin executing code. + (Naturally, frame is currently the youngest + [visible frame][vf].) This method should return + a [resumption value][rv] specifying how the debuggee's execution should + proceed. + + SpiderMonkey only calls `onEnterFrame` to report + [visible][vf], non-`"debugger"` frames. + +onThrow(frame, value) (future plan) +: The exception value is being thrown by frame, which is + running debuggee code. This method should return a + [resumption value][rv] specifying how the debuggee's execution should + proceed. If it returns `undefined`, the exception is thrown as normal. + + A call to the `onThrow` handler is typically followed by one or more + calls to the `onExceptionUnwind` handler. + + *(pending discussion)* If the debuggee executes + `try { throw 0; } finally { f(); }` and `f()` executes without error, + the `onThrow` handler is called only once. The debugger is not notified + when the exception is set aside in order to execute the `finally` block, + nor when it is restored after the `finally` block completes normally. + + *(An alternative design here would be: onException(status, frame, value) + where status is one of the strings "throw", "unwind", "catch", + "finally", "rethrow". JS\_SaveExceptionState would trigger a "finally" + event, JS\_RestoreExceptionState would trigger a "rethrow", + JS\_ClearPendingException would trigger a "catch"; not sure what + JS\_DropExceptionState or a return/throw from a finally block should + do.)* + +onExceptionUnwind(frame, value) +: The exception value has been thrown, and has propagated to + frame; frame is the youngest remaining stack frame, and is a + debuggee frame. This method should return a [resumption value][rv] + specifying how the debuggee's execution should proceed. If it returns + `undefined`, the exception continues to propagate as normal: if control in + `frame` is in a `try` block, control jumps to the corresponding `catch` or + `finally` block; otherwise, frame is popped, and the exception + propagates to frame's caller. + + When an exception's propagation causes control to enter a `finally` + block, the exception is temporarily set aside. If the `finally` block + finishes normally, the exception resumes propagation, and the debugger's + `onExceptionUnwind` handler is called again, in the same frame. (The + other possibility is for the `finally` block to exit due to a `return`, + `continue`, or `break` statement, or a new exception. In those cases the + old exception does not continue to propagate; it is discarded.) + +sourceHandler(ASuffusionOfYellow) +: This method is never called. If it is ever called, a contradiction has + been proven, and the debugger is free to assume that everything is true. + +onError(frame, report) +: SpiderMonkey is about to report an error in frame. Report + is an object describing the error, with the following properties: + + `message` + : The fully formatted error message. + + `file` + : If present, the source file name, URL, etc. (If this property is + present, the line property will be too, and vice versa.) + + `line` + : If present, the source line number at which the error occurred. + + `lineText` + : If present, this is the source code of the offending line. + + `offset` + : The index of the character within lineText at which the error occurred. + + `warning` + : Present and true if this is a warning; absent otherwise. + + `strict` + : Present and true if this error or warning is due to the strict option + (not to be confused with ES strict mode) + + `exception` + : Present and true if an exception will be thrown; absent otherwise. + + `arguments` + : An array of strings, representing the arguments substituted into the + error message. + + This method's return value is ignored. + +`onNewGlobalObject(global)` +: A new global object, global, has been created. The application + embedding the JavaScript implementation may provide details about what + kind of global it is via global.hostAnnotations. + + This handler method should return a [resumption value][rv] specifying how + the debuggee's execution should proceed. However, note that a { return: + value } resumption value is treated like `undefined` ("continue + normally"); value is ignored. (Allowing the handler to substitute + its own value for the new global object doesn't seem useful.) + + This handler method is only available to debuggers running in privileged + code ("chrome", in Firefox). Most functions provided by this `Debugger` + API observe activity in only those globals that are reachable by the + API's user, thus imposing capability-based restrictions on a + `Debugger`'s reach. However, the `onNewGlobalObject` method allows the + API user to monitor all global object creation that occurs anywhere + within the JavaScript system (the "JSRuntime", in SpiderMonkey terms), + thereby escaping the capability-based limits. For this reason, + `onNewGlobalObject` is only available to privileged code. + + + +## Function Properties of the Debugger Prototype Object + +The functions described below may only be called with a `this` value +referring to a `Debugger` instance; they may not be used as methods of +other kinds of objects. + +addDebuggee(global) +: Add the global object designated by global to the set of global + objects this `Debugger` instance is debugging. If the designated global + is already a debuggee, this has no effect. Return this `Debugger`'s + [`Debugger.Object`][object] instance referring to the designated global. + + The value global may be any of the following: + + * A global object. + + * An HTML5 `WindowProxy` object (an "outer window", in Firefox + terminology), which is treated as if the `Window` object of the + browsing context's active document (the "inner window") were passed. + + * A cross-compartment wrapper of an object; we apply the prior rules to + the wrapped object. + + * A [`Debugger.Object`][object] instance belonging to this `Debugger` instance; + we apply the prior rules to the referent. + + * Any other sort of value is treated as a `TypeError`. (Note that each + rule is only applied once in the process of resolving a given + global argument. Thus, for example, a [`Debugger.Object`][object] + referring to a second [`Debugger.Object`][object] which refers to a global does + not designate that global for the purposes of this function.) + + The global designated by global must be in a different + compartment than this `Debugger` instance itself. If adding the + designated global's compartment would create a cycle of debugger and + debuggee compartments, this method throws an error. + + This method returns the [`Debugger.Object`][object] instance whose referent is + the designated global object. + + The `Debugger` instance does not hold a strong reference to its + debuggee globals: if a debuggee global is not otherwise reachable, then + it is dropped from the `Debugger`'s set of debuggees. (Naturally, the + [`Debugger.Object`][object] instance this method returns does hold a strong + reference to the added global.) + +removeDebuggee(global) +: Remove the global object designated by global from this + `Debugger` instance's set of debuggees. Return `undefined`. + + This method interprets global using the same rules that + [`addDebuggee`][add] does. + +hasDebuggee(global) +: Return `true` if the global object designated by global is a + debuggee of this `Debugger` instance. + + This method interprets global using the same rules that + [`addDebuggee`][add] does. + +`getDebuggees()` +: Return an array of distinct [`Debugger.Object`][object] instances whose referents + are all the global objects this `Debugger` instance is debugging. + + Since `Debugger` instances don't hold strong references to their + debuggee globals, if a debuggee global is otherwise unreachable, it may + be dropped at any moment from the array this method returns. + +`getNewestFrame()` +: Return a [`Debugger.Frame`][frame] instance referring to the youngest + [visible frame][vf] currently on the calling thread's stack, or `null` + if there are no visible frames on the stack. + +findSources([query]) (not yet implemented) +: Return an array of all [`Debugger.Source`][source] instances matching + query. Each source appears only once in the array. Query + is an object whose properties restrict which sources are returned; a + source must meet all the criteria given by query to be returned. + If query is omitted, we return all sources of all debuggee + scripts. + + Query may have the following properties: + + `url` + : The source's `url` property must be equal to this value. + + `global` + : The source must have been evaluated in the scope of the given global + object. If this property's value is a [`Debugger.Object`][object] instance + belonging to this `Debugger` instance, then its referent is used. If the + object is not a global object, then the global in whose scope it was + allocated is used. + + Note that the result may include sources that can no longer ever be + used by the debuggee: say, eval code that has finished running, or + source for unreachable functions. Whether such sources appear can be + affected by the garbage collector's behavior, so this function's result + is not entirely deterministic. + +findScripts([query]) +: Return an array of [`Debugger.Script`][script] instances for all debuggee scripts + matching query. Each instance appears only once in the array. + Query is an object whose properties restrict which scripts are + returned; a script must meet all the criteria given by query to + be returned. If query is omitted, we return the [`Debugger.Script`][script] + instances for all debuggee scripts. + + Query may have the following properties: + + `url` + : The script's `url` property must be equal to this value. + + `source` (not yet implemented) + : The script's `source` property must be equal to this value. + + `line` + : The script must at least partially cover the given source line. If this + property is present, the `url` property must be present as well. + + `column` + : The script must include given column on the line given by the `line` + property. If this property is present, the `url` and `line` properties + must both be present as well. + + `innermost` + : If this property is present and true, the script must be the innermost + script covering the given source location; scripts of enclosing code are + omitted. + + `global` + : The script must be in the scope of the given global object. If this + property's value is a [`Debugger.Object`][object] instance belonging to this + `Debugger` instance, then its referent is used. If the object is not a + global object, then the global in whose scope it was allocated is used. + + All properties of query are optional. Passing an empty object + returns all debuggee code scripts. + + Note that the result may include [`Debugger.Script`][script] instances for + scripts that can no longer ever be used by the debuggee, say, those for + eval code that has finished running, or unreachable functions. Whether + such scripts appear can be affected by the garbage collector's + behavior, so this function's behavior is not entirely deterministic. + +clearBreakpoint(handler) +: Remove all breakpoints set in this `Debugger` instance that use + handler as their handler. Note that, if breakpoints using other + handler objects are set at the same location(s) as handler, they + remain in place. + +`clearAllBreakpoints()` +: Remove all breakpoints set using this `Debugger` instance. + +`clearAllWatchpoints()` (future plan) +: Clear all watchpoints owned by this `Debugger` instance. + +`findAllGlobals()` +: Return an array of [`Debugger.Object`][object] instances referring to all the + global objects present in this JavaScript instance. The application may + provide details about what kind of globals they are via the + [`Debugger.Object`][object] instances' `hostAnnotations` accessors. + + The results of this call can be affected in non-deterministic ways by + the details of the JavaScript implementation. The array may include + [`Debugger.Object`][object] instances referring to global objects that are not + actually reachable by the debuggee or any other code in the system. + (Naturally, once the function has returned, the array's + [`Debugger.Object`][object] instances strongly reference the globals they refer + to.) + + This handler method is only available to debuggers running in privileged + code ("chrome", in Firefox). Most functions provided by this `Debugger` + API observe activity in only those globals that are reachable by the + API's user, thus imposing capability-based restrictions on a + `Debugger`'s reach. However, `findAllGlobals` allows the API user to + find all global objects anywhere within the JavaScript system (the + "JSRuntime", in SpiderMonkey terms), thereby escaping the + capability-based limits. For this reason, `findAllGlobals` is only + available to privileged code. + +makeGlobalObjectReference(global) +: Return the [`Debugger.Object`][object] whose referent is the global object + designated by global, without adding the designated global as a + debuggee. If global does not designate a global object, throw a + `TypeError`. Determine which global is designated by global + using the same rules as [`Debugger.prototype.addDebuggee`][add]. +