summaryrefslogtreecommitdiffstats
path: root/js/src/doc/Debugger/Tutorial-Breakpoint.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/doc/Debugger/Tutorial-Breakpoint.md')
-rw-r--r--js/src/doc/Debugger/Tutorial-Breakpoint.md133
1 files changed, 133 insertions, 0 deletions
diff --git a/js/src/doc/Debugger/Tutorial-Breakpoint.md b/js/src/doc/Debugger/Tutorial-Breakpoint.md
new file mode 100644
index 0000000000..55b8681857
--- /dev/null
+++ b/js/src/doc/Debugger/Tutorial-Breakpoint.md
@@ -0,0 +1,133 @@
+Tutorial: Set a breakpoint using `Debugger`
+===========================================
+
+This page shows how you can try out the [`Debugger` API][debugger] yourself
+using Firefox's Scratchpad. We use `Debugger` to set a breakpoint in a function,
+and then evaluate an expression whenever it is hit.
+
+This tutorial was tested against Firefox 58 Beta and Nightly. It does not work in Firefox 57.
+
+1. Since the `Debugger` API is only available to privileged JavaScript code,
+ you'll need to use the Browser Content Toolbox to try it out. To do this,
+ open the Firefox developer tools, click on the options gear at the upper
+ right of the toolbox, and make sure that both “Enable browser chrome and
+ add-on debugging toolboxes” and “Enable remote debugging” are checked. These
+ are located at the bottom right of the options panel; you may need to scroll
+ to see them. Once they're checked, you can close the developer tools.
+
+
+2. Save the following text to an HTML file:
+
+ ```html
+ <div onclick="report('the best div');">Click me!</div>
+ <div onclick="report('another great div');">Or me!</div>
+ <script>
+ function report(what) {
+ console.log('clicked: ' + what);
+ }
+ </script>
+ ```
+
+3. Visit the HTML file in your browser, and open the Browser Content Toolbox by
+ opening the Firefox menu, choosing “Browser Tools”, and then “Browser
+ Content Toolbox”. If that item doesn't appear in the “Browser Tools” menu,
+ make sure you checked both boxes to enable the Browser Content Toolbox as
+ explained in Step 1.
+
+4. Our example code is long enough that the best way to run it is to use the
+ Scratchpad panel, which is not enabled by default. To enable it, click on
+ the options gear at the upper right of the Browser Content Toolbox, and make
+ sure the “Scratchpad” box in the “Default Developer Tools” section the left
+ is checked. The Scratchpad panel should appear at the top of the Toolbox
+ alongside the Console, Debugger, and Memory panels.
+
+5. Click on the Scratchpad panel and enter the following code:
+
+ ```js
+ const { addDebuggerToGlobal } = ChromeUtils.importESModule(
+ "resource://gre/modules/jsdebugger.sys.mjs"
+ );
+ const { console } = ChromeUtils.importESModule(
+ "resource://gre/modules/Console.sys.mjs"
+ );
+
+ // This simply defines 'Debugger' in this Scratchpad;
+ // it doesn't actually start debugging anything.
+ addDebuggerToGlobal(globalThis);
+
+ // Create a 'Debugger' instance.
+ var dbg = new Debugger;
+
+ // Make the tab's top window a debuggee, and get a
+ // Debugger.Object referring to the window.
+ var windowDO = dbg.addDebuggee(tabs[0].content);
+
+ // Get a Debugger.Object referring to the window's `report`
+ // function.
+ var reportDO = windowDO.getOwnPropertyDescriptor('report').value;
+
+ // Set a breakpoint at the entry point of `report`.
+ reportDO.script.setBreakpoint(0, {
+ hit: function (frame) {
+ console.log('hit breakpoint in ' + frame.callee.name);
+ console.log('what = ' + frame.eval('what').return);
+ }
+ });
+
+ console.log('Finished setting breakpoint!');
+ ```
+
+6. In the Scratchpad, ensure that no text is selected, and press the "Run"
+ button.
+
+ Now, click on the text that says "Click me!" in the web page.
+ This runs the `div` element's `onclick` handler.
+ When control reaches the start of the `report` function,
+ `Debugger` calls the breakpoint handler's `hit` method,
+ passing a `Debugger.Frame` instance.
+ The `hit` method logs the breakpoint hit to the browser content toolbox's console.
+ Then it evaluates the expression `what` in the given stack frame, and logs its result.
+ The toolbox's console now looks like this:
+
+ ![The breakpoint handler's console output][img-example-console]
+ <!-- HTML comment prevents caption, which MDN styles poorly -->
+
+ You can also click on the text that says “Or me!”, to see `report` called from a
+ different handler.
+
+ If `Debugger` is unable to find the `report` function, or the console output
+ does not appear, evaluate the expression `tabs[0].content.document.location`
+ in the console to make sure that `tabs[0]` indeed refers to the HTML file you
+ visited. If you have more than one tab visiting a `file:` URL, they all share
+ a single content process, so you may need to use a different element of the
+ array as the debuggee.
+
+7. Press "Run" in the Scratchpad again. Now, clicking on "Click me!" causes the
+ breakpoint hit to be logged twice---one for each `Debugger` instance.
+
+ Multiple `Debugger` instances can observe the same debuggee. Re-running the code
+ in the Scratchpad creates a fresh `Debugger` instance, adds the same web page as
+ its debuggee, and then sets a new breakpoint. When you click on the `div`
+ element, both `Debugger`s' breakpoints are hit, and both handlers run.
+
+ This shows how any number of `Debugger`-based tools can observe a single web
+ page simultaneously. In fact, you can use the Browser Content Toolbox's Debugger
+ panel to set its own breakpoint in `report`, and it will trigger along with the
+ first two. Keep in mind, however, that when multiple Debuggers share a debuggee,
+ the order in which their handlers run is not specified. If more than one tool
+ tries to influence the debuggee's behavior, their combined behavior could be
+ unpredictable.
+
+8. Close the web page and the Browser Content Toolbox.
+
+ Since both the Scratchpad's global object and the debuggee window are
+ now gone, the `Debugger` instances will be garbage collected, since
+ they can no longer have any visible effect on Firefox's behavior. The
+ `Debugger` API tries to interact with garbage collection as
+ transparently as possible; for example, if both a `Debugger.Object`
+ instance and its referent are not reachable, they will both be
+ collected, even while the `Debugger` instance to which the shadow
+ belonged continues to exist.
+
+[debugger]: Debugger-API.md
+[img-example-console]: console.png