教程:设置断点

此页面展示了如何使用 Firefox 的 Scratchpad 自己尝试 调试器 API。我们使用 Debugger 在函数中设置断点,并在每次命中时评估表达式。

此教程已针对 Firefox 58 Beta 版和 Nightly 版进行了测试。它在 Firefox 57 中不起作用。

  1. 由于 Debugger API 仅对特权 JavaScript 代码可用,因此您需要使用浏览器内容工具箱来试用它。为此,请打开 Firefox 开发者工具,点击工具箱右上角的选项齿轮,并确保选中“启用浏览器 chrome 和附加组件调试工具箱”和“启用远程调试”。这些位于选项面板的右下角;您可能需要滚动才能看到它们。选中后,您可以关闭开发者工具。


  1. 将以下文本保存到 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>


  1. 在浏览器中访问 HTML 文件,并通过打开 Firefox 菜单、选择“浏览器工具”,然后选择“浏览器内容工具箱”来打开浏览器内容工具箱。如果“Web 开发人员”菜单中未显示该项目,请确保您已选中两个复选框以启用浏览器内容工具箱,如步骤 1 中所述。


  1. 我们的示例代码足够长,因此运行它的最佳方法是使用 Scratchpad 面板,该面板默认情况下未启用。要启用它,请点击浏览器内容工具箱右上角的选项齿轮,并确保选中左侧“默认开发者工具”部分中的“Scratchpad”复选框。Scratchpad 面板应出现在工具箱顶部的控制台、调试器和内存面板旁边。


  1. 点击 Scratchpad 面板并输入以下代码

const { addDebuggerToGlobal } = ChromeUtils.importESModule(
  "resource://gre/modules/jsdebugger.sys.mjs"
);
const { console } = ChromeUtils.importESModule(
  "resource://gre/modules/Console.sys.mjs"
);

// This 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!');


  1. 在 Scratchpad 中,确保未选中任何文本,然后按“运行”按钮。

    现在,点击网页中显示“点击我!”的文本。这将运行 div 元素的 onclick 处理程序。当控制权到达 report 函数的开头时,Debugger 调用断点处理程序的 hit 方法,并传递一个 Debugger.Frame 实例。 hit 方法将断点命中记录到浏览器内容工具箱的控制台。然后,它在给定的堆栈帧中评估表达式 what,并记录其结果。工具箱的控制台现在如下所示

    The breakpoint handler’s console output

    您也可以点击显示“或者我!”的文本,以查看从不同处理程序调用的 report

    如果 Debugger 无法找到 report 函数,或者控制台输出未出现,请在控制台中评估表达式 tabs[0].content.document.location 以确保 tabs[0] 确实引用了您访问的 HTML 文件。如果您有多个选项卡访问 file: URL,则它们共享一个内容进程,因此您可能需要使用数组的不同元素作为调试对象。


  1. 再次按 Scratchpad 中的“运行”。现在,点击“点击我!”会导致断点命中被记录两次——每个 Debugger 实例各一次。

多个 Debugger 实例可以观察相同的调试对象。在 Scratchpad 中重新运行代码会创建一个新的 Debugger 实例,将相同的网页添加为其调试对象,然后设置一个新的断点。当您点击 div 元素时,两个 Debugger 的断点都会命中,并且两个处理程序都会运行。

这展示了任意数量基于 Debugger 的工具如何可以同时观察单个网页。实际上,您可以使用浏览器内容工具箱的调试器面板在 report 中设置自己的断点,它将与前两个一起触发。但是,请记住,当多个调试器共享一个调试对象时,其处理程序运行的顺序未指定。如果多个工具试图影响调试对象的行为,则它们的组合行为可能是不可预测的。


  1. 关闭网页和浏览器内容工具箱。

由于 Scratchpad 的全局对象和调试对象窗口现在都消失了,因此 Debugger 实例将被垃圾回收,因为它们不再对 Firefox 的行为有任何可见影响。 Debugger API 试图尽可能透明地与垃圾回收交互;例如,如果 Debugger.Object 实例及其引用对象都不可访问,则它们都将被回收,即使属于该阴影的 Debugger 实例继续存在。

源代码元数据

从文件生成

js/src/doc/Debugger/Tutorial-Breakpoint.md

水印

sha256:c8dd4bb69972b58e59fcbe6870499206463a5e330fda25f1214893595a1c01d0

变更集

ffa775dd5bd4