Debugger: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(→‎Debugging hooks: Describe "slow script"-style termination. Explain what non-function code is.)
(Replace with a link to the new MDN page.)
 
(185 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The Debug object provides functions for debugging code running in a separate compartment. You can provide functions for SpiderMonkey to call when events like steps, calls, and breakpoint hits occur in the debuggee, examine the debuggee's stack frames, and inspect and manipulate the debuggee's objects.
The documentation for the <code>Debugger</code> API has moved to the Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Tools/Debugger-API
 
Debug object event hook functions run in the same thread as the debuggee, on the same stack: when the event occurs, the debuggee pauses while your hook functions run, and resumes (unless you say otherwise) when your functions return.
 
The debugger and debuggee must be in separate compartments. Your hook functions run in the debugger's compartment. SpiderMonkey mediates their access to the debuggee's objects, and prevents the debuggee from accessing the debugger's objects at all.
The Debug object provides objects representing the debuggee's stack frames, scripts, and other internal interpreter structures, for your hook functions to examine and manipulate.
 
==Debugger access to debuggee values==
 
The <code>Debug</code> object follows certain conventions to help debuggers safely inspect and modify the debuggee's objects and values. Primitive values are passed freely between debugger and debuggee; copying or wrapping is handled transparently, as appropriate. Objects (including host objects like DOM nodes) received from the debuggee are fronted in the debugger by <code>Debug.Object</code> instances (described in detail below), which provide reflection-oriented methods for inspecting the referent object's properties and other characteristics. Of the debugger's objects, only <code>Debug.Object</code> instances may be passed to the debuggee: when this occurs, the debuggee receives the <code>Debug.Object</code>'s referent, not the Debug.Object instance itself.
 
In the descriptions below, the term "debuggee value" means either a primitive value or a <code>Debug.Object</code> instance; it is a value that might be received from the debuggee, or that could be passed to the debuggee.
 
==Beginning to Debug==
 
To begin debugging another compartment's code, you create a Debug object for the debuggee compartment, and install your hook functions.
 
<dl>
<dt>Debug(<i>object</i>)
<dd>Create a debugger object debugging <i>object</i>'s compartment. <i>Object</i> is typically a global object, but can be any JavaScript object from the debuggee's compartment.
 
The <i>object</i> must be in a different compartment than the calling code, and debugger/debuggee compartments may not form a cycle. <i>Object</i>'s compartment must not be in use by another thread while this call runs.
 
<dt><i>D</i>.setHooks(<i>hooks</i>)
<dd>Use the functions in <i>hooks</i> to handle events occurring in D's debuggee. <i>Hooks</i> should be an object; each property should be named after a debugging event, and its value should be a function SpiderMonkey should call when the named event occurs. See below for descriptions of specific debugging hooks.
 
This removes all previously registered hooks; after the call, only the hooks mentioned in <i>hooks</i> are in force. Thus, a call like <code><i>D</i>.setHooks({})</code> removes all debugging hooks.
 
Hook function calls are cross-compartment, same-thread calls. Hook functions run in the thread in which the event occurred, not in the thread that registered the hooks. (It is your responsibility to ensure that two threads don't try to run in the same compartment). Hook functions run in the compartment to which they belong, not in the debuggee's compartment.
 
<dt><i>D</i>.getHooks()
<dd>Return an object holding all the event hooks currently in force. The returned object is suitable for use with <code><i>D</i>.setHooks</code>.
</dl>
 
==Debugging hooks==
 
For each debugging hook, we give the name of the hook and the arguments passed to its handler function, and describe the circumstances under which SpiderMonkey calls it.
 
<dl>
<dt>interrupt(<i>frame</i>)
<dd>A bytecode instruction is about to execute in the stack frame represented by <i>frame</i>, a <code>Debug.Frame</code> instance. Naturally, <i>frame</i> is the youngest debuggee frame.
 
This hook function's return value determines how execution should continue:
<ul>
<li>If it returns true, execution continues normally.
<li>If it returns an object of the form <code>{ throw: <i>value</i> }</code>, then <i>value</i> is thrown as an exception from the current bytecode instruction. <i>value</i> must be a debuggee value.
<li>If it returns an object of the form <code>{ return: <i>value</i> }</code>, then <i>value</i> is immediately returned as the current value of the function. <i>value</i> must be a debuggee value.
<li>If it returns null, the calling code is terminated, as if it had been cancelled by the "slow script" dialog box.
<li>If the hook throws an exception, ... well, we're in trouble. That's an error in the debugger which should be reported somehow, but certainly not handled by the debuggee.
</ul>
 
<dt>newScript(<i>script</i>, [<i>function</i>])
<dd>New code, represented by the <code>Debug.Script</code> instance <i>script</i>, has been loaded into the debuggee's compartment. If the new code is part of a function, <i>function</i> is a Debug.Object reference to the function object. (Not all code is part of a function; for example, the code appearing in a <code>&lt;script&gt;</code> tag that is outside of any functions defined in that tag would be passed to <code>newScript</code> without an accompanying <i>function</i> argument.)
 
Note that <i>script</i> may be a temporary script, created for a call to <i>eval</i> and destroyed when its execution is complete.
 
<dt>destroyScript(<i>script</i>)
<dd>SpiderMonkey has determined that <i>script</i> will no longer be needed, and is about to throw it away. The garbage collector may have found that the script is no longer in use, or perhaps <i>eval</i> has finished executing the script, and is about to destroy it. In any case, operations on <i>script</i> after this hook function returns will throw an error.
 
<dt>debuggerHandler(<i>frame</i>)
<dd>The debuggee has executed a <i>debugger</i> statement in <i>frame</i>. This hook function's return value determines how execution proceeds, as for the <i>interrupt</i> hook function.
 
<dt>sourceHandler(<i>ASuffusionOfYellow</i>)
<dd>This hook function is never called. If it is ever called, a contradiction has been proven, and the debugger is free to assume that everything is true.
 
<dt>enterFrame(<i>frame</i>, <i>call</i>)
<dd>The stack frame <i>frame</i> is about to begin executing code. (Naturally, <i>frame</i> is currently the youngest debuggee frame.) If <i>call</i> is true, it is a function call; if <i>call</i> is false, it is global or eval code.
 
If this hook function returns a function <i>f</i>, SpiderMonkey will call <i>f</i> when execution of <i>frame</i> completes, passing one argument indicating how it completed.
<ul>
<li>If the argument is of the form <code>{ return: <i>value</i> }</code>, then the code completed normally, yielding <i>value</i>. <i>Value</i> is a debuggee value.
<li>If the argument is of the form <code>{ throw: <i>value</i> }</code>, then the code threw <i>value</i> as an exception. <i>Value</i> is a debuggee value.
<li>If the argument is <code>null</code>, then the code was terminated, as if by the "slow script" dialog box.
</ul>
 
<dt>throw(<i>frame</i>, <i>value</i>)
<dd>The code running in <i>frame</i> is about to throw <i>value</i> as an exception. The value this hook function returns determines how execution proceeds, as for <i>interrupt</i>.
 
<dt>error(<i>frame</i>, <i>report</i>)
<dd>SpiderMonkey is about to report an error in <i>frame</i>. <i>Report</i> is an object describing the error, with the following properties:
 
<dl>
<dt><code>message</code>
<dd>The fully formatted error message.
<dt><code>file</code>
<dd>If present, the source file name, URL, etc. (If this property is present, the <i>line</i> property will be too, and vice versa.)
<dt><code>line</code>
<dd>If present, the source line number at which the error occurred.
<dt><code>lineText</code>
<dd>If present, this is the source code of the offending line.
<dt><code>offset</code>
<dd>The index of the character within lineText at which the error occurred.
<dt><code>warning</code>
<dd>Present and true if this is a warning; absent otherwise.
<dt><code>strict</code>
<dd>Present and true if this error or warning is due to the strict option (not to be confused with ES strict mode)
<dt><code>exception</code>
<dd>Present and true if an exception will be thrown; absent otherwise.
<dt><code>arguments</code>
<dd>An array of strings, representing the arguments substituted into the error message.
</dl>
</dl>
 
==Debug.Frame==
 
==Debug.Script==
 
weak reference
 
== Debug.Object==
 
strong reference

Latest revision as of 04:40, 16 April 2014

The documentation for the Debugger API has moved to the Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Tools/Debugger-API