aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/tools/debugger-api/index.html
blob: f7c20b6ebfa7dd827864ce2131a7cac915a945ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
---
title: Debugger-API
slug: Tools/Debugger-API
translation_of: Tools/Debugger-API
---
<div>{{ToolsSidebar}}</div>

<h1 id="Debugger_接口"><code>Debugger</code> 接口</h1>

<p>Mozilla 的JS引擎, <strong>SpiderMonkey</strong>, 提供了一个名为<code>Debugger</code> 的调试接口,开发者能够通过该接口使用JS代码观测和操纵另一端JS代码的运行. Firefox内置的开发者工具和 Firebug 插件都使用<code>Debugger</code> 来是实现它们的JavaScript调试器.同时,<code>Debugger</code> 也被广泛应用与实现其他类型的工具,例如tracers, coverage analysis, patch-and-continue等。</p>

<p><code>Debugger</code> 有三个基本的特点:</p>

<ul>
 <li>
  <p>It is a <em>source level</em> interface: it operates in terms of the JavaScript language, not machine language. It operates on JavaScript objects, stack frames, environments, and code, and presents a consistent interface regardless of whether the debuggee is interpreted, compiled, or optimized. If you have a strong command of the JavaScript language, you should have all the background you need to use <code>Debugger</code> successfully, even if you have never looked into the language’s implementation.</p>
 </li>
 <li>
  <p>It is for use <em>by JavaScript code</em>. JavaScript is both the debuggee language and the tool implementation language, so the qualities that make JavaScript effective on the web can be brought to bear in crafting tools for developers. As is expected of JavaScript APIs, <code>Debugger</code> is a <em>sound</em> interface: using (or even misusing) <code>Debugger</code> should never cause Gecko to crash. Errors throw proper JavaScript exceptions.</p>
 </li>
 <li>
  <p>It is an <em>intra-thread</em> debugging API. Both the debuggee and the code using <code>Debugger</code> to observe it must run in the same thread. Cross-thread, cross-process, and cross-device tools must use <code>Debugger</code> to observe the debuggee from within the same thread, and then handle any needed communication themselves. (Firefox’s builtin tools have a <a href="https://wiki.mozilla.org/Remote_Debugging_Protocol" title="Remote Debugging Protocol">protocol</a> defined for this purpose.)</p>
 </li>
</ul>

<p>In Gecko, the <code>Debugger</code> API is available to chrome code only. By design, it ought not to introduce security holes, so in principle it could be made available to content as well; but it is hard to justify the security risks of the additional attack surface.</p>

<p>The <code>Debugger</code> API cannot currently observe self-hosted JavaScript. This is not inherent in the API’s design, but simply that the self-hosting infrastructure isn’t prepared for the kind of invasions the <code>Debugger</code> API can perform.</p>

<h2 id="Debugger_实例与影子对象">Debugger 实例与影子对象</h2>

<p><code>Debugger</code> reflects every aspect of the debuggee’s state as a JavaScript value—not just actual JavaScript values like objects and primitives, but also stack frames, environments, scripts, and compilation units, which are not normally accessible as objects in their own right.</p>

<p>Here is a JavaScript program in the process of running a timer callback function:</p>

<div class="figure"><img alt="A running JavaScript program and its Debugger shadows" src="https://mdn.mozillademos.org/files/7225/shadows.svg">
<p class="caption">A running JavaScript program and its Debugger shadows</p>
</div>

<p>This diagram shows the various types of shadow objects that make up the Debugger API (which all follow some <a href="Debugger-API/Conventions" title="Debugger API: General Conventions">general conventions</a>):</p>

<ul>
 <li>
  <p>A <a href="Debugger-API/Debugger.Object" title="Debugger.Object"><code>Debugger.Object</code></a> represents a debuggee object, offering a reflection-oriented API that protects the debugger from accidentally invoking getters, setters, proxy traps, and so on.</p>
 </li>
 <li>
  <p>A <a href="Debugger-API/Debugger.Script" title="Debugger.Script"><code>Debugger.Script</code></a> represents a block of JavaScript code—either a function body or a top-level script. Given a <code>Debugger.Script</code>, one can set breakpoints, translate between source positions and bytecode offsets (a deviation from the “source level” design principle), and find other static characteristics of the code.</p>
 </li>
 <li>
  <p>A <a href="Debugger-API/Debugger.Frame" title="Debugger.Frame"><code>Debugger.Frame</code></a> represents a running stack frame. You can use these to walk the stack and find each frame’s script and environment. You can also set <code>onStep</code> and <code>onPop</code> handlers on frames.</p>
 </li>
 <li>
  <p>A <a href="Debugger-API/Debugger.Environment" title="Debugger.Environment"><code>Debugger.Environment</code></a> represents an environment, associating variable names with storage locations. Environments may belong to a running stack frame, captured by a function closure, or reflect some global object’s properties as variables.</p>
 </li>
</ul>

<p>The <a href="Debugger-API/Debugger" title="The Debugger object"><code>Debugger</code></a> instance itself is not really a shadow of anything in the debuggee; rather, it maintains the set of global objects which are to be considered debuggees. A <code>Debugger</code> observes only execution taking place in the scope of these global objects. You can set functions to be called when new stack frames are pushed; when new code is loaded; and so on.</p>

<p>Omitted from this picture are <a href="Debugger-API/Debugger.Source" title="Debugger.Source"><code>Debugger.Source</code></a> instances, which represent JavaScript compilation units. A <code>Debugger.Source</code> can furnish a full copy of its source code, and explain how the code entered the system, whether via a call to <code>eval</code>, a <code>&lt;script&gt;</code> element, or otherwise. A <code>Debugger.Script</code> points to the <code>Debugger.Source</code> from which it is derived.</p>

<p>Also omitted is the <code>Debugger</code>’s <a href="Debugger-API/Debugger.Memory" title="Debugger.Memory"><code>Debugger.Memory</code></a> instance, which holds methods and accessors for observing the debuggee’s memory use.</p>

<p>All these types follow some <a href="Debugger-API/Conventions" title="Debugger API: General Conventions">general conventions</a>, which you should look through before drilling down into any particular type’s specification.</p>

<p>All shadow objects are unique per <code>Debugger</code> and per referent. For a given <code>Debugger</code>, there is exactly one <code>Debugger.Object</code> that refers to a particular debuggee object; exactly one <code>Debugger.Frame</code> for a particular stack frame; and so on. Thus, a tool can store metadata about a shadow’s referent as a property on the shadow itself, and count on finding that metadata again if it comes across the same referent. And since shadows are per-<code>Debugger</code>, tools can do so without worrying about interfering with other tools that use their own <code>Debugger</code> instances.</p>

<h2 id="Examples">Examples</h2>

<p>Here are some things you can try out yourself that show off some of <code>Debugger</code>’s features:</p>

<ul>
 <li>
  <p><a href="Debugger-API/Tutorial-Breakpoint" title="Tutorial: Evaluate an expression when a breakpoint is hit">Setting a breakpoint</a> in a page, running a handler function when it is hit that evaluates an expression in the page’s context.</p>
 </li>
 <li>
  <p><a href="Debugger-API/Tutorial-Allocation-Log-Tree" title="Tutorial: the allocation log">Showing how many objects different call paths allocate.</a></p>
 </li>
</ul>

<h2 id="Gecko-specific_features">Gecko-specific features</h2>

<p>While the <code>Debugger</code> core API deals only with concepts common to any JavaScript implementation, it also includes some Gecko-specific features:</p>

<ul>
 <li>[Global tracking][global] supports debugging all the code running in a Gecko instance at once—the ‘chrome debugging’ model.</li>
 <li>[Object wrapper][wrapper] functions help manipulate object references that cross privilege boundaries.</li>
</ul>

<h4 id="Source_Metadata">Source Metadata</h4>

<dl>
 <dt>Generated from file:</dt>
 <dt></dt>
 <dd>js/src/doc/Debugger/Debugger-API.md</dd>
 <dt>Watermark:</dt>
 <dd id="watermark">sha256:6ee2381145a0d2e53d2f798f3f682e82dd7ab0caa0ac4dd5e56601c2e49913a7</dd>
 <dt>Changeset:</dt>
 <dd><a href="https://hg.mozilla.org/mozilla-central/rev/ffa775dd5bd4">ffa775dd5bd4</a></dd>
</dl>