调试器

Debugger 对象

当作为构造函数调用时,Debugger 对象会创建一个新的 Debugger 实例。

new Debugger([global, …])

创建一个调试器对象,并将其 addDebuggee 方法应用到每个给定的 global 对象上,将其作为初始被调试对象。

Debugger 原型对象的访问器属性

一个 Debugger 实例从其原型继承以下访问器属性

enabled

一个布尔值,指示此 Debugger 实例的处理程序、断点等当前是否启用。它是一个具有 getter 和 setter 的访问器属性:对其赋值会启用或禁用此 Debugger 实例;读取它会在实例启用时产生 true,否则产生 false。此属性在新建的 Debugger 实例中最初为 true

此属性为调试器代码提供了一个控制点,用于将其与被调试对象分离,而不管我们在接口中添加了何种事件或处理程序或“点”。

allowUnobservedAsmJS

一个布尔值,指示在此 Debugger 实例的被调试对象全局中运行的 asm.js 代码是否对 Debugger API 处理程序和断点不可见。将其设置为 false 会抑制提前编译 asm.js 并强制 asm.js 代码作为普通 JavaScript 运行。这是一个具有 getter 和 setter 的访问器属性。在新建的 Debugger 实例中最初为 false

将此标志设置为 true 用于 Debugger API 的子系统的用途(例如,Debugger.Source),而不是单步调试目标 JavaScript 程序。

allowWasmBinarySource

一个布尔值,指示 WebAssembly 源代码是否以二进制形式可用。WebAssembly 文本生成将被禁用。

collectCoverageInfo

一个布尔值,指示是否应在此 Debugger 实例的每个被调试对象内部启用代码覆盖率。更改此标志值将重新编译所有 JIT 代码以添加或删除代码覆盖率检测。当被调试对象的任何帧当前在堆栈上处于活动状态时更改此标志将产生异常。

将其设置为 true 会启用代码覆盖率检测,可以通过 Debugger.Script getOffsetsCoverage 函数访问。在某些情况下,代码覆盖率可能会公开早于修改此标志的信息。代码覆盖率报告是单调的,因此可以在启用 Debugger 时获取快照并输出差异。

将其设置为 false 会阻止此 Debugger 实例需要任何代码覆盖率检测,但不能保证检测不存在。

uncaughtExceptionHook

要么是 null,要么是一个函数,SpiderMonkey 在调用调试事件处理程序、断点处理程序或类似函数时抛出某些异常时会调用该函数,我们在此处将其称为 调试器异常。在调试器中抛出的异常不会传播到被调试对象代码;相反,SpiderMonkey 会调用此函数,将 调试器异常 作为其唯一参数传递,并将 Debugger 实例作为 this 值传递。此函数应返回一个恢复值,该值确定被调试对象应如何继续。

如果未捕获异常钩子本身抛出异常 未捕获钩子异常,SpiderMonkey 会向被调试对象抛出一个新的错误对象 向被调试对象承认异常,其消息指责调试器,并包含 未捕获钩子异常 和原始 调试器异常 的文本描述。

如果 uncaughtExceptionHook 的值为 null,SpiderMonkey 会向被调试对象抛出一个异常,其消息指责调试器,并包含 调试器异常 的文本描述。

将除可调用值或 null 之外的任何内容分配给此属性会抛出一个 TypeError 异常。

(这不是处理调试器错误的理想方法,但这里的希望是,即使不完美,某种后备措施也会让调试器开发人员的生活更轻松。例如,未捕获异常钩子可能可以访问浏览器级别的功能,如 alert 函数,而此 API 的实现则没有,从而可以以适合上下文的方式向开发人员显示调试器错误。)

调试器处理程序函数

每个 Debugger 实例都继承访问器属性,您可以使用这些属性存储处理程序函数,以便在发生给定事件时 SpiderMonkey 调用这些函数。

当下面描述的事件之一在被调试对象代码中发生时,引擎会暂停被调试对象并在观察被调试对象的每个 Debugger 实例上调用相应的调试处理程序。处理程序函数接收 Debugger 实例作为其 this 值。大多数处理程序函数可以返回一个恢复值,指示被调试对象的执行应如何继续。

在新的 Debugger 实例中,这些属性中的每一个最初都是 undefined。分配给调试处理程序的任何值必须是函数或 undefined;否则会抛出 TypeError

处理程序函数在发生事件的同一线程中运行。它们在它们所属的区室中运行,而不是在被调试对象的区室中运行。

onNewScript(script, global)

Debugger.Script 实例 script 表示的新代码已加载到被调试对象的范围内。

此方法的返回值被忽略。

onNewPromise(promise)

一个新的 Promise 对象(由 Debugger.Object 实例 promise 引用)已在被调试对象的范围内分配。可以使用 Debugger.Object 实例 promisepromiseAllocationStack 访问器属性获取 Promise 的分配堆栈。

此处理程序方法应返回一个恢复值,指定被调试对象的执行应如何继续。但是,请注意,{ return: value } 恢复值被视为 undefined(“正常继续”);value 被忽略。

onPromiseSettled(promise)

一个 Promise 对象(由在被调试对象范围内分配的 Debugger.Object 实例 promise 引用)已完成(已完成或已拒绝)。可以使用 Debugger.Object 实例 promise 的与 Promise 相关的访问器属性获取 Promise 的状态、完成或拒绝值以及分配和解析堆栈。

此处理程序方法应返回一个恢复值,指定被调试对象的执行应如何继续。但是,请注意,{ return: value } 恢复值被视为 undefined(“正常继续”);value 被忽略。

onDebuggerStatement(frame)

被调试对象代码在 frame 中执行了 debugger 语句。此方法应返回一个恢复值,指定被调试对象的执行应如何继续。

onEnterFrame(frame)

堆栈 frame 即将开始执行代码。(当然,frame 当前是最年轻的 可见帧。)此方法应返回一个恢复值,指定被调试对象的执行应如何继续。

SpiderMonkey 仅调用 onEnterFrame 来报告 可见的、非 "debugger" 帧。

onExceptionUnwind(frame, value)

异常 value 已抛出并已传播到 frameframe 是剩余的最年轻的堆栈帧,并且是调试器帧。此方法应返回一个恢复值,指定被调试对象的执行应如何继续。如果它返回 undefined,则异常会像往常一样继续传播:如果 frame 中的控制位于 try 块中,则控制跳转到相应的 catchfinally 块;否则,frame 会弹出,并且异常会传播到 frame 的调用方。

当由于过递归或内存不足异常导致控制进入 finally 块时,异常会暂时搁置。如果 finally 块正常完成,则异常将恢复传播,并且调试器的 onExceptionUnwind 处理程序将在同一帧中再次被调用。(另一种可能性是 finally 块由于 returncontinuebreak 语句或新的异常而退出。在这些情况下,旧异常不会继续传播;它会被丢弃。)

由于过递归或内存不足异常导致帧展开时,不会调用此处理程序。

sourceHandler(ASuffusionOfYellow)

此方法永远不会被调用。如果它被调用,则已证明存在矛盾,调试器可以自由地假设一切都是真的。

onError(frame, report)

SpiderMonkey 即将在 frame 中报告错误。Report 是一个描述错误的对象,具有以下属性

message

完全格式化的错误消息。

file

如果存在,则为源文件名、URL 等。(如果此属性存在,则 line 属性也会存在,反之亦然。)

line

如果存在,则为发生错误的源代码行号。

lineText

如果存在,则为有问题的行的源代码。

offset

发生错误时在 lineText 中的字符索引。

warning

存在且为 true 表示这是一个警告;否则不存在。

strict

存在且为 true 表示此错误或警告是由于 strict 选项造成的(不要与 ES 严格模式混淆)

exception

存在且为 true 表示将抛出异常;否则不存在。

arguments

一个字符串数组,表示替换到错误消息中的参数。

此方法的返回值被忽略。

onNewGlobalObject(global)

创建了一个新的全局对象 global

此处理程序方法应返回一个恢复值,指定调试目标的执行应如何继续。但是,请注意,{ return: value } 恢复值被视为 undefined(“正常继续”);value 将被忽略。(允许处理程序用其自己的值替换新的全局对象似乎没有用。)

此处理程序方法仅对在特权代码(Firefox 中为“chrome”)中运行的调试器可用。此 Debugger API 提供的大多数函数仅观察 API 用户可访问的那些全局变量中的活动,从而对 Debugger 的范围施加基于功能的限制。但是,onNewGlobalObject 方法允许 API 用户监视 JavaScript 系统(在 SpiderMonkey 术语中为“JSRuntime”)中任何位置发生的所有全局对象创建,从而摆脱基于功能的限制。因此,onNewGlobalObject 仅对特权代码可用。

Debugger 原型对象的函数属性

下面描述的函数只能使用引用 Debugger 实例的 this 值来调用;它们不能用作其他类型对象的函数。

addDebuggee(global)

将由 global 指定的全局对象添加到此 Debugger 实例正在调试的全局对象集中。如果指定的全局对象已经是调试目标,则此操作无效。返回此 Debugger Debugger.Object 实例,该实例引用指定的全局对象。

global 的值可以是以下任何一种

  • 全局对象。

  • HTML5 WindowProxy 对象(在 Firefox 术语中为“外部窗口”),其处理方式如同传递了浏览上下文活动文档(“内部窗口”)的 Window 对象。

  • 对象的跨隔室包装器;我们将先前规则应用于包装的对象。

  • 属于此 Debugger 实例的 Debugger.Object 实例;我们将先前规则应用于其引用对象。

  • 任何其他类型的价值都被视为 TypeError。(请注意,在解析给定的 global 参数的过程中,每个规则只应用一次。因此,例如,引用第二个引用全局对象的 Debugger.ObjectDebugger.Object 不会为该函数的目的指定该全局对象。)

global 指定的全局对象必须位于与此 Debugger 实例本身不同的隔室中。如果添加指定的全局对象的隔室会导致调试器和调试目标隔室的循环,则此方法将引发错误。

此方法返回其引用对象是指定全局对象的 Debugger.Object 实例。

Debugger 实例不会对其实时调试目标全局对象持有强引用:如果调试目标全局对象无法通过其他方式访问,则它将从 Debugger 的调试目标集中删除。(当然,此方法返回的 Debugger.Object 实例确实对添加的全局对象持有强引用。)

如果此调试器正在跟踪分配站点并且无法跟踪 global 的分配站点,则此方法将抛出 Error

addAllGlobalsAsDebuggees()

此方法类似于addDebuggee,但会将所有隔室中的所有全局对象添加到此 Debugger 实例的调试目标集中。请注意,它会跳过此调试器的隔室。

如果此调试器正在跟踪分配站点并且无法跟踪某些全局对象的分配站点,则此方法将抛出 Error。否则,此方法将返回 undefined

此处理程序方法仅对在特权代码(Firefox 中为“chrome”)中运行的调试器可用。此 Debugger API 提供的大多数函数仅观察 API 用户可访问的那些全局变量中的活动,从而对 Debugger 的范围施加基于功能的限制。但是,addAllGlobalsAsDebuggees 方法允许 API 用户监视 JavaScript 系统(在 SpiderMonkey 术语中为“JSRuntime”)中任何位置发生的所有全局对象创建,从而摆脱基于功能的限制。因此,addAllGlobalsAsDebuggees 仅对特权代码可用。

removeDebuggee(global)

从此 Debugger 实例的调试目标集中删除由 global 指定的全局对象。返回 undefined

此方法使用与 addDebuggee 相同的规则来解释 global

从此 Debugger 中删除全局对象作为调试目标会清除该全局对象中属于该 Debugger 的所有断点。

removeAllDebuggees()

从此 Debugger 实例的调试目标集中删除所有全局对象。返回 undefined

hasDebuggee(global)

如果由 global 指定的全局对象是此 Debugger 实例的调试目标,则返回 true

此方法使用与 addDebuggee 相同的规则来解释 global

getDebuggees()

返回一个由不同的 Debugger.Object 实例组成的数组,其引用对象是此 Debugger 实例正在调试的所有全局对象。

由于 Debugger 实例不会对其实时调试目标全局对象持有强引用,因此,如果调试目标全局对象无法通过其他方式访问,则它可能会随时从此方法返回的数组中删除。

getNewestFrame()

返回一个引用当前在调用线程的堆栈上最年轻的可见帧Debugger.Frame 实例,或者如果堆栈上没有可见帧,则返回 null

findSources([query]) (not yet implemented)

返回与 query 匹配的所有 Debugger.Source 实例的数组。每个源在数组中只出现一次。Query 是一个对象,其属性限制了返回哪些源;源必须满足 query 给出的所有条件才能返回。如果省略 query,我们将返回所有调试目标脚本的所有源。

Query 可以具有以下属性

url

源的 url 属性必须等于此值。

global

源必须在给定全局对象的范围内进行评估。如果此属性的值是属于此 Debugger 实例的 Debugger.Object 实例,则使用其引用对象。如果对象不是全局对象,则使用其在其中分配的全局对象。

请注意,结果可能包含调试目标不再能够使用的源:例如,已完成运行的 eval 代码或无法访问的函数的源代码。此类源是否出现会受到垃圾回收器行为的影响,因此此函数的结果并非完全确定性的。

findScripts([query])

返回与 query 匹配的所有调试目标脚本的 Debugger.Script 实例的数组。每个实例在数组中只出现一次。Query 是一个对象,其属性限制了返回哪些脚本;脚本必须满足 query 给出的所有条件才能返回。如果省略 query,我们将返回所有调试目标脚本的 Debugger.Script 实例。

Query 可以具有以下属性

url

脚本的 url 属性必须等于此值。

source

脚本的 source 属性必须等于此值。

line

脚本必须至少部分覆盖给定的源代码行。如果存在此属性,则 url 属性也必须存在。

innermost

如果此属性存在且为 true,则脚本必须是覆盖给定源代码位置的最内部脚本;将省略封闭代码的脚本。

global

脚本必须在给定全局对象的范围内。如果此属性的值是属于此 Debugger 实例的 Debugger.Object 实例,则使用其引用对象。如果对象不是全局对象,则使用其在其中分配的全局对象。

query 的所有属性都是可选的。传递一个空对象将返回所有调试目标代码脚本。

请注意,结果可能包含调试目标不再能够使用的脚本的 Debugger.Script 实例,例如,已完成运行的 eval 代码或无法访问的函数的脚本。此类脚本是否出现会受到垃圾回收器行为的影响,因此此函数的行为并非完全确定性的。

findObjects([query])

返回一个 Debugger.Object 实例数组,这些实例引用在与 query 匹配的调试目标全局对象的范围内分配的每个实时对象。每个实例在数组中只出现一次。Query 是一个对象,其属性限制了返回哪些对象;对象必须满足 query 给出的所有条件才能返回。如果省略 query,我们将返回在调试目标全局对象的范围内分配的所有对象的 Debugger.Object 实例。

query 对象可以具有以下属性

class

如果存在,则仅返回其内部 [[Class]] 的名称与给定字符串匹配的对象。请注意,在某些情况下,给定构造函数的原型对象具有与其引用它的实例相同的 [[Class]],但本身不能用作该类的有效实例。通过类名收集对象的代码可能需要进一步检查它们,然后再尝试使用它们。

query 的所有属性都是可选的。传递一个空对象将返回调试目标全局对象中的所有对象。

findScripts 不同,此函数是确定性的,并且永远不会返回引用以前无法访问的对象(尚未被收集)的 <a href=”Debugger.Object”>``Debugger.Object``s</a>。

clearBreakpoint(handler)

删除在此 Debugger 实例中设置的所有使用 handler 作为其处理程序的断点。请注意,如果使用其他处理程序对象的断点设置在与 handler 相同的位置,则它们将保留在原位。

clearAllBreakpoints()

删除使用此 Debugger 实例设置的所有断点。

findAllGlobals()

返回一个 Debugger.Object 实例数组,这些实例引用此 JavaScript 实例中存在的所有全局对象。

此调用的结果可能会受到 JavaScript 实现细节的非确定性方式的影响。该数组可能包含引用调试目标或系统中任何其他代码实际上无法访问的全局对象的 Debugger.Object 实例。(当然,一旦函数返回,数组的 Debugger.Object 实例就会强烈引用它们引用的全局对象。)

此处理程序方法仅对在特权代码(Firefox 中为“chrome”)中运行的调试器可用。此 Debugger API 提供的大多数函数仅观察 API 用户可访问的那些全局变量中的活动,从而对 Debugger 的范围施加基于功能的限制。但是,findAllGlobals 允许 API 用户查找 JavaScript 系统(在 SpiderMonkey 术语中为“JSRuntime”)中任何位置的所有全局对象,从而摆脱基于功能的限制。因此,findAllGlobals 仅对特权代码可用。

makeGlobalObjectReference(global)

返回其引用对象是 global 指定的全局对象的 Debugger.Object,而无需将指定的全局对象添加为调试目标。如果 global 没有指定全局对象,则抛出 TypeError。使用与 <a href=”Debugger#addDebuggee” title=”The Debugger object: addDebuggee”>``Debugger.prototype.addDebuggee``</a> 相同的规则确定 global 指定的全局对象。

adoptDebuggeeValue(value)

给定一个由任意 Debugger 拥有的调试目标值 value,返回由此 Debugger 拥有的等效调试目标值。

如果value是原始值,则保持不变并返回。如果value是任意Debugger拥有的Debugger.Object,则返回由当前Debugger拥有的等效Debugger.Object。否则,如果value是其他类型的对象,因此不是正确的调试目标值,则抛出 TypeError 异常。

Debugger 对象的静态方法

下面描述的函数不会使用this值进行调用。

isCompilableUnit(source)

给定一段由source指定的源代码字符串,如果该字符串可以通过添加更多行变成有效的 JavaScript 语句,则返回 false。否则返回 true。目的是支持交互式编译 - 在缓冲区中累积行,直到 isCompilableUnit 为 true,然后将其传递给编译器。

源代码元数据

生成自文件

js/src/doc/Debugger/Debugger.md

水印

sha256:03b36132885e046a5f213130ba22b1139b473770f7324b842483c09ab7665f7c

变更集

e91b2c85aacd