Source code

Revision control

Other Tools

1
# Remote Debugging Protocol
2
3
The Mozilla debugging protocol allows a debugger to connect to a browser, discover what sorts of things are present to debug or inspect, select JavaScript threads to watch, and observe and modify their execution. The protocol provides a unified view of JavaScript, DOM nodes, CSS rules, and the other technologies used in client-side web applications. The protocol ought to be sufficiently general to be extended for use with other sorts of clients (profilers, say) and servers (mail readers; random XULrunner applications).
4
5
All communication between debugger (client) and browser (server) is in the form of JSON objects. This makes the protocol directly readable by humans, capable of graceful evolution, and easy to implement using stock libraries. In particular, it should be easy to create mock implementations for testing and experimentation.
6
7
The protocol operates at the JavaScript level, not at the C++ or machine level, and assumes that the JavaScript implementation itself is healthy and responsive. The JavaScript program being executed may well have gone wrong, but the JavaScript implementation's internal state must not be corrupt. Bugs in the implementation may cause the debugger to fail; bugs in the interpreted program must not.
8
9
## General Conventions
10
11
### Actors
12
13
An **actor** is something on the server that can exchange JSON packets with the client. Every packet from the client specifies the actor to which it is directed, and every packet from the server indicates which actor sent it.
14
15
Each server has a root actor, with which the client first interacts. The root actor can explain what sort of thing the server represents (browser; mail reader; etc.), and enumerate things available to debug: tabs, chrome, and so on. Each of these, in turn, is represented by an actor to which requests can be addressed. Both artifacts of the program being debugged, like JavaScript objects and stack frames, and artifacts of the debugging machinery, like breakpoints and watchpoints, are actors with whom packets can be exchanged.
16
17
For example, a debugger might connect to a browser, ask the root actor to list the browser's tabs, and present this list to the developer. If the developer chooses some tabs to debug, then the debugger can send `attach` requests to the actors representing those tabs, to begin debugging.
18
19
Actor names are JSON strings, containing no spaces or colons. The name of the root actor is `"root"`.
20
21
To allow the server to reuse actor names and the resources they require, actors have limited lifetimes. All actors in a server form a tree, whose root is the root actor. Closing communications with an actor automatically closes communications with its descendants. For example, the actors representing a thread's stack frames are children of the actor representing the thread itself, so that when a debugger detaches from a thread, which closes the thread's actor, the frames' actors are automatically closed. This arrangement allows the protocol to mention actors liberally, without making the client responsible for explicitly closing every actor that has ever been mentioned.
22
23
When we say that some actor *A* is a child of some actor *B*, we mean that *A* is a direct child of *B*, not a grandchild, great-grandchild, or the like. Similarly, **parent** means "direct parent". We use the terms **ancestor** and **descendent** to refer to those looser relationships.
24
25
The root actor has no parent, and lives as long as the underlying connection to the client does; when that connection is closed, all actors are closed.
26
27
Note that the actor hierarchy does not, in general, correspond to any particular hierarchy appearing in the debuggee. For example, although web workers are arranged in a hierarchy, the actors representing web worker threads are all children of the root actor: one might want to detach from a parent worker while continuing to debug one of its children, so it doesn't make sense to close communications with a child worker simply because one has closed communications with its parent.
28
29
*(We are stealing the "actor" terminology from Mozilla's IPDL, to mean, roughly, "things participating in the protocol". However, IPDL does much more with the idea than we do: it treats both client and server as collections of actors, and uses that detail to statically verify properties of the protocol. In contrast, the debugging protocol simply wants a consistent way to indicate the entities to which packets are directed.)*
30
31
### Packets
32
33
The protocol is carried by a reliable, bi-directional byte stream; data sent in both directions consists of JSON objects, called packets. A packet is a top-level JSON object, not contained inside any other value.
34
35
Every packet sent from the client has the form:
36
37
```
38
{ "to":actor, "type":type, ... }
39
```
40
41
where `actor` is the name of the actor to whom the packet is directed and `type` is a string specifying what sort of packet it is. Additional properties may be present, depending on `type`.
42
43
Every packet sent from the server has the form:
44
45
```
46
{ "from":actor, ... }
47
```
48
49
where `actor` is the name of the actor that sent it. The packet may have additional properties, depending on the situation.
50
51
If a packet is directed to an actor that no longer exists, the server sends a packet to the client of the following form:
52
53
```
54
{ "from":actor, "error":"noSuchActor" }
55
```
56
57
where `actor` is the name of the non-existent actor. (It is strange to receive messages from actors that do not exist, but the client evidently believes that actor exists, and this reply allows the client to pair up the error report with the source of the problem.)
58
59
Clients should silently ignore packet properties they do not recognize. We expect that, as the protocol evolves, we will specify new properties that can appear in existing packets, and experimental implementations will do the same.
60
61
### Common Patterns of Actor Communication
62
63
Each type of actor specifies which packets it can receive, which it might send, and when it can do each. Although in principle these interaction rules could be complex, in practice most actors follow one of two simple patterns:
64
65
* **Request/Reply**: Each packet sent to the actor ("request") elicits a single packet in response ("reply").
66
* **Request/Reply/Notify**: Like Request/Reply, but the actor may send packets that are not in response to any specific request ("notification"), perhaps announcing events that occur spontaneously in the debuggee.
67
68
These patterns are described in more detail below.
69
70
Some actors require more complicated rules. For example, the set of packets accepted by a [Thread-like actor](#interacting-with-thread-like-actors) depends on which one of four states it occupies. The actor may spontaneously transition from one state to another, and not all state transitions produce notification packets. Actors like this require careful specification.
71
72
#### The Request/Reply Pattern
73
74
In this specification, if we call a packet a **request**, then it is a packet sent by the client, which always elicits a single packet from the actor in return, the **reply**. These terms indicate a simple pattern of communication: the actor processes packets in the order they are received, and the client can trust that the *i*'th reply corresponds to the *i*'th request.
75
76
An [error reply packet](#error-packets) from a request/reply actor constitutes a reply.
77
78
Note that it is correct for a client to send several requests to a request/reply actor without waiting for a reply to each request before sending the next; requests can be pipelined. However, as the pending requests consume memory, the client should ensure that only a bounded number of requests are outstanding at any one time.
79
80
#### The Request/Reply/Notify Pattern
81
82
Some actors follow the request/reply pattern, but may also send the client ***notification*** packets, not in reply to any particular request. For example, if the client sends the root actor a `["listTabs"](#listing-browser-tabs)` request, then the root actor sends a reply. However, since the client has now expressed an interest in the list of open tabs, the root actor may subsequently send the client a `"tabListChanged"` notification packet, indicating that the client should re-fetch the list of tabs if it is interested in the latest state.
83
84
There should be a small upper bound on the number of notification packets any actor may send between packets received from the client, to ensure that the actor does not flood the client. In the example above, the root actor sends at most one `"tabListChanged"` notification after each `"listTabs"` request.
85
86
#### Error Packets
87
88
Any actor can reply to a packet it is unable to process with an **error reply** of the form:
89
90
```
91
{ "from":actor, "error":name, "message":message }
92
```
93
94
where *name* is a JSON string naming what went wrong, and *message* is an English error message. Error *names* are specified by the protocol; the client can use the name to identify which error condition arose. The *message* may vary from implementation to implementation, and should only be displayed to the user as a last resort, as the server lacks enough information about the user interface context to provide appropriate messages.
95
96
If an actor receives a packet whose type it does not recognize, it sends an error reply of the form:
97
98
```
99
{ "from":actor, "error":"unrecognizedPacketType", "message":message }
100
```
101
102
where *message* provides details to help debugger developers understand what went wrong: what kind of actor actor is; the packet received; and so on.
103
104
If an actor receives a packet which is missing needed parameters (say, an `"autocomplete"` packet with no `"text"` parameter), it sends an error reply of the form:
105
106
```
107
{ "from":actor, "error":"missingParameter", "message":message }
108
```
109
110
where *message* provides details to help debugger developers fix the problem.
111
112
If an actor receives a packet with a parameter whose value is inappropriate for the operation, it sends an error reply of the form:
113
114
```
115
{ "from":actor, "error":"badParameterType", "message":message }
116
```
117
118
where *message* provides details to help debugger developers fix the problem. (Some packets' descriptions specify more specific errors for particular circumstances.)
119
120
### Grips
121
122
A grip is a JSON value that refers to a specific JavaScript value in the debuggee. Grips appear anywhere an arbitrary value from the debuggee needs to be conveyed to the client: stack frames, object property lists, lexical environments, `paused` packets, and so on.
123
124
For mutable values like objects and arrays, grips do not merely convey the value's current state to the client. They also act as references to the original value, by including an actor to which the client can send messages to modify the value in the debuggee.
125
126
A grip has one of the following forms:
127
128
```
129
value
130
```
131
132
where value is a string, a number, or a boolean value. For these types of values, the grip is simply the JSON form of the value.
133
134
```
135
{ "type":"null" }
136
```
137
138
This represents the JavaScript `null` value. (The protocol does not represent JavaScript `null` simply by the JSON `null`, for the convenience of clients implemented in JavaScript: this representation allows such clients to use `typeof(grip) == "object"` to decide whether the grip is simple or not.)
139
140
```
141
{ "type":"undefined" }
142
```
143
144
This represents the JavaScript `undefined` value. (`undefined` has no direct representation in JSON.)
145
146
```
147
{ "type":"Infinity" }
148
```
149
150
This represents the JavaScript `Infinity` value. (`Infinity` has no direct representation in JSON.)
151
152
```
153
{ "type":"-Infinity" }
154
```
155
156
This represents the JavaScript `-Infinity` value. (`-Infinity` has no direct representation in JSON.)
157
158
```
159
{ "type":"NaN" }
160
```
161
162
This represents the JavaScript `NaN` value. (`NaN` has no direct representation in JSON.)
163
164
```
165
{ "type":"-0" }
166
```
167
168
This represents the JavaScript `-0` value. (`-0` stringifies to JSON as 0.)
169
170
```
171
{ "type":"object", "class":className, "actor":actor }
172
```
173
174
This represents a JavaScript object whose class is `className`. (Arrays and functions are treated as objects for the sake of forming grips.) Actor can be consulted for the object's contents, as explained below.
175
176
If the class is "Function", the grip may have additional properties:
177
178
```
179
{ "type":"object", "class":"Function", "actor":actor,
180
"name":name, "displayName":displayName,
181
"userDisplayName":userDisplayName,
182
"url":url, "line":line, "column":column }
183
```
184
185
These additional properties are:
186
187
***Name***
188
189
The function's name (as given in the source code, following the `function` keyword), as a string. If the function is anonymous, the `name` property is omitted.
190
191
***displayName***
192
193
A name the system has inferred for the function (say, `"Foo.method"`). If the function has a given name (appearing in the grip as the `"name"` property), or if the system was unable to infer a suitable name for it, the `displayName` property is omitted.
194
195
***userDisplayName***
196
197
If the function object has a `"displayName"` value property whose value is a string, this is that property's value. (Many JavaScript development tools consult such properties, to give developers a way to provide their own meaningful names for functions.)
198
199
***url***
200
201
The URL of the function's source location (see [Source Locations](#source-locations));
202
203
***line***
204
205
The line number of the function's source location (see [Source Locations](#source-locations));
206
207
***column***
208
209
The column number of the function's source location (see [Source Locations](#source-locations));
210
211
```
212
{ "type":"longString", "initial":initial, "length":length, "actor":actor }
213
```
214
215
This represents a very long string, where "very long" is defined at the server's discretion. `Initial` is some initial portion of the string, `length` is the string's full length, and actor can be consulted for the rest of the string, as explained below.
216
217
For example, the following table shows some JavaScript expressions and the grips that would represent them in the protocol:
218
219
| JavaScript Expression | Grip |
220
|:--------------------------------------------------------:|:---------------------------------------------------------------------------------------------:|
221
| 42 | 42 |
222
| true | true |
223
| "nasu" | "nasu" |
224
| (void 0) | `{ "type":"undefined" }` |
225
| ({x:1}) | `{ "type":"object", "class":"Object", "actor":"24" }` |
226
| "Arms and the man I sing, who, *[much, much more text]*" | `{ "type":"longString", "initial":"Arms and the man I sing", "length":606647, "actor":"25" }` |
227
228
Garbage collection will never free objects visible to the client via the protocol. Thus, actors representing JavaScript objects are effectively garbage collection roots.
229
230
#### Objects
231
232
While a thread is paused, the client can send requests to the actors appearing in object grips to examine the objects they represent in more detail.
233
234
##### Property Descriptors
235
236
Protocol requests that describe objects' properties to the client often use **descriptors**, JSON values modeled after ECMAScript 5's property descriptors, to describe individual properties.
237
238
A descriptor has the form:
239
240
```
241
{ "enumerable":<enumerable>, "configurable":<configurable>, ... }
242
```
243
244
where *enumerable* and *configurable* are boolean values indicating whether the property is enumerable and configurable, and additional properties are present depending on what sort of property it is.
245
246
A descriptor for a data property has the form:
247
248
```
249
{ "enumerable":<enumerable>, "configurable":<configurable>,
250
"value":<value>, "writeable":<writeable> }
251
```
252
253
where *value* is a grip on the property's value, and *writeable* is a boolean value indicating whether the property is writeable.
254
255
A descriptor for an accessor property has the form:
256
257
```
258
{ "enumerable":<enumerable>, "configurable":<configurable>,
259
"get":<getter>, "set":<setter> }
260
```
261
262
where *getter* and *setter* are grips on the property's getter and setter functions. These may be `{ "type":"undefined" }` if the property lacks the given accessor function.
263
264
A **safe getter value descriptor** provides a value that an inherited accessor returned when applied to an instance. (See [Finding An Object's Prototype And Properties](#finding-an-objects-prototype-and-properties) for an explanation of why and when such descriptors are used.) Such a descriptor has the form:
265
266
```
267
{ "getterValue": <value>, "getterPrototypeLevel": <level>,
268
"enumerable":<enumerable>, "writable":<writable> }
269
```
270
271
where *value* is a grip on the value the getter returned, *level* is the number of steps up the object's prototype chain one must take to find the object on which the getter appears as an own property. If the getter appears directly on the object, *level* is zero. The *writable* property is true if the inherited accessor has a setter, and false otherwise.
272
273
For example, if the JavaScript program being debugged evaluates the expression:
274
275
```
276
({x:10, y:"kaiju", get a() { return 42; }})
277
```
278
279
then a grip on this value would have the form:
280
281
```
282
{ "type":"object", "class":"Object", "actor":<actor> }
283
```
284
285
and sending a ["prototypeAndProperties"](#finding-an-objects-prototype-and-properties) request to *actor* would produce the following reply:
286
287
```
288
{ "from":<actor>, "prototype":{ "type":"object", "class":"Object", "actor":<objprotoActor> },
289
"ownProperties":{ "x":{ "enumerable":true, "configurable":true, "writeable":true, "value":10 },
290
"y":{ "enumerable":true, "configurable":true, "writeable":true, "value":"kaiju" },
291
"a":{ "enumerable":true, "configurable":true,
292
"get":{ "type":"object", "class":"Function", "actor":<getterActor> },
293
"set":{ "type":"undefined" }
294
}
295
}
296
}
297
```
298
299
300
Sending a ["prototypeAndProperties"](#finding-an-objects-prototype-and-properties) request to an object actor referring to a DOM mouse event might produce the following reply:
301
302
```
303
{ "from":<mouseEventActor>, "prototype":{ "type":"object", "class":"MouseEvent", "actor":<mouseEventProtoActor> },
304
"ownProperties":{ }
305
"safeGetterValues":{ "screenX": { "getterValue": 1000, "getterPrototypeLevel": 1,
306
"enumerable": true, "writable": false },
307
"screenY": { "getterValue": 1000, "getterPrototypeLevel": 1,
308
"enumerable": true, "writable": false },
309
"clientX": { "getterValue": 800, "getterPrototypeLevel": 1,
310
"enumerable": true, "writable": false },
311
"clientY": { "getterValue": 800, "getterPrototypeLevel": 1,
312
"enumerable": true, "writable": false },
313
...
314
}
315
}
316
```
317
318
##### Finding An Object's Prototype And Properties
319
320
To examine an object's prototype and properties, a client can send the object's grip's actor a request of the form:
321
322
```
323
{ "to":<gripActor>, "type":"prototypeAndProperties" }
324
```
325
326
to which the grip actor replies:
327
328
```
329
{ "from":<gripActor>, "prototype":<prototype>, "ownProperties":<ownProperties> }
330
```
331
332
where *prototype* is a grip on the object's prototype (possibly `{ "type":"null" }`), and *ownProperties* has the form:
333
334
```
335
{ name:<descriptor>, ... }
336
```
337
338
with a *name*:<descriptor> pair for each of the object's own properties.
339
340
The web makes extensive use of inherited accessor properties; for example, the `clientX` and `clientY`> properties of a mouse click event are actually accessor properties which the event object inherits from its prototype chain. It can be very valuable to display such properties' values directly on the object (taking care to distinguish them from true "own" properties), if the server can determine that the getters can be called without side effects.
341
342
To this end, when possible, the server may provide safe getter value descriptors for an object, as described in [Property Descriptors](#property-descriptors) above, reporting the values that getter functions found on the object's prototype chain return when applied to that object. If the server chooses to provide any, the reply includes a `"safeGetterValues"` property of the form:
343
344
```
345
{ name:<descriptor>, ... }
346
```
347
348
with a *name*:<descriptor> pair for each safe getter the object inherits from its prototype chain, or that appears directly on the object. Each *descriptor* here is a safe getter value descriptor.
349
350
*TODO: What about objects with many properties?*
351
352
##### Finding an Object's Prototype
353
354
355
To find an object's prototype, a client can send the object's grip's actor a request of the form:
356
357
```
358
{ "to":<gripActor>, "type":"prototype" }
359
```
360
361
to which the grip actor replies:
362
363
```
364
{ "from":<gripActor>, "prototype":<prototype> }
365
```
366
367
where *prototype* is a grip on the object's prototype (possibly `{ "type":"null" }`).
368
369
370
##### Listing an Object's Own Properties' Names
371
372
To list an object's own properties' names, a client can send the object's grip's actor a request of the form:
373
374
```
375
{ "to":<gripActor>, "type":"ownPropertyNames" }
376
```
377
378
to which the grip actor replies:
379
380
```
381
{ "from":<gripActor>, "ownPropertyNames":[ <name>, ... ] }
382
```
383
384
where each *name* is a string naming an own property of the object.
385
386
##### Finding Descriptors For Single Properties
387
388
To obtain a descriptor for a particular property of an object, a client can send the object's grip's actor a request of the form:
389
390
```
391
{ "to":<gripActor>, "type":"property", "name":<name> }
392
```
393
394
to which the grip actor replies:
395
396
```
397
{ "from":<gripActor>, "descriptor":<descriptor> }
398
```
399
400
where *descriptor* is a descriptor for the own property of the object named *name*, or `null` if the object has no such own property.
401
402
A property descriptor has the form:
403
404
```
405
{ "configurable":<configurable>, "enumerable":<enumerable>, ... }
406
```
407
408
where *configurable* and *enumerable* are boolean values. *Configurable* is true if the property can be deleted or have its attributes changed. *Enumerable* is true if the property will be enumerated by a `for-in` enumeration.
409
410
Descriptors for value properties have the form:
411
412
```
413
{ "configurable":<configurable>, "enumerable":<enumerable>,
414
"writable":<writable>, "value":<value> }
415
```
416
417
where *writable* is `true` if the property's value can be written to; *value* is a grip on the property's value; and *configurable* and *enumerable* are as described above.
418
419
Descriptors for accessor properties have the form:
420
421
```
422
{ "configurable":<configurable>, "enumerable":<enumerable>,
423
"get":<get>, "set":<set> }
424
```
425
426
where *get* and *set* are grips on the property's getter and setter functions; either or both are omitted if the property lacks the given accessor function. *Configurable* and *enumerable* are as described above.
427
428
*TODO: assign to value property*
429
430
*TODO: special stuff for arrays*
431
432
*TODO: special stuff for functions*
433
434
*TODO: find function's source position*
435
436
*TODO: get function's named arguments, in order*
437
438
*TODO: descriptors for Harmony proxies*
439
440
##### Functions
441
442
If an object's class as given in the grip is `"Function"`, then the grip's actor responds to the messages given here.
443
444
```
445
{ "to":<functionGripActor>, "type":"parameterNames" }
446
```
447
448
This requests the names of the parameters of the function represented by *functionGripActor*. The reply has the form:
449
450
```
451
{ "from":<functionGripActor>, "parameterNames":[ <parameter>, ... ] }
452
```
453
454
where each *parameter* is the name of a formal parameter to the function as a string. If the function takes destructuring arguments, then *parameter* is a structure of JSON array and object forms matching the form of the destructuring arguments.
455
456
```
457
{ "to":<functionGripActor>, "type":"scope" }
458
```
459
460
Return the lexical environment over which the function has closed. The reply has the form:
461
462
```
463
{ "from":<functionGripActor>, "scope":<environment> }
464
```
465
466
where *environment* is a [lexical environment](#lexical-environments). Note that the server only returns environments of functions in a context being debugged; if the function's global scope is not the browsing context to which we are attached, the function grip actor sends an error reply of the form:
467
468
```
469
{ "from":<functionGripActor>, "error":"notDebuggee", "message":<message> }
470
```
471
472
where *message* is text explaining the problem.
473
474
```
475
{ "to":<functionGripActor>, "type":"decompile", "pretty":<pretty> }
476
```
477
478
Return JavaScript source code for a function equivalent to the one represented by *functionGripActor*. If the optional `pretty` parameter is present and *pretty* is `true`, then produce indented source code with line breaks. The reply has the form:
479
480
```
481
{ "from":<functionGripActor>, "decompiledCode":<code> }
482
```
483
484
where *code* is a string.
485
486
If *functionGripActor*'s referent is not a function, or is a function proxy, the actor responds to these requests with an error reply of the form:
487
488
```
489
{ "from":<functionGripActor>, "error":"objectNotFunction", message:<message> }
490
```
491
492
where *message* is a string containing any additional information that would be helpful to debugger developers.
493
494
#### Long Strings
495
496
The client can find the full contents of a long string by sending a request to the long string grip actor of the form:
497
498
```
499
{ "to":<gripActor>, "type":"substring", "start":<start>, "end":<end> }
500
```
501
502
where *start* and *end* are integers. This requests the substring starting at the *start*'th character, and ending before the *end*'th character. The actor replies as follows:
503
504
```
505
{ "from":<gripActor>, "substring":<string> }
506
```
507
508
where *string* is the requested portion of the string the actor represents. Values for *start* less than zero are treated as zero; values greater than the length of the string are treated as the length of the string. Values for *end* are treated similarly. If *end* is less than *start*, the two values are swapped. (This is meant to be the same behavior as JavaScript's `String.prototype.substring`.)
509
510
As with any other actor, the client may only send messages to a long string grip actor while it is alive: for [pause-lifetime grips](#grip-lifetimes), until the debuggee is resumed; or for [thread-lifetime grips](#grip-lifetimes), until the thread is detached from or exits. However, unlike object grip actors, the client may communicate with a long string grip actor at any time the actor is alive, regardless of whether the debuggee is paused. (Since strings are immutable values in JavaScript, the responses from a long string grip actor cannot depend on the actions of the debuggee.)
511
512
#### Grip Lifetimes
513
514
Most grips are **pause-lifetime** grips: they last only while the JavaScript thread is paused, and become invalid as soon as the debugger allows the thread to resume execution. (The actors in pause-lifetime grips are children of an actor that is closed when the thread resumes, or is detached from.) This arrangement allows the protocol to use grips freely in responses without requiring the client to remember and close them all.
515
516
However, in some cases the client may wish to retain a reference to an object or long string while the debuggee runs. For example, a panel displaying objects selected by the user must update its view of the objects each time the debuggee pauses. To carry this out, the client can promote a pause-lifetime grip to a **thread-lifetime** grip, which lasts until the thread is detached from or exits. Actors in thread-lifetime grips are children of the thread actor. When the client no longer needs a thread-lifetime grip, it can explicitly release it.
517
518
Both pause-lifetime and thread-lifetime grips are garbage collection roots.
519
520
To promote a pause-lifetime grip to a thread-lifetime grip, the client sends a packet of the form:
521
522
```
523
{ "to":<gripActor>, "type":"threadGrip" }
524
```
525
526
where *gripActor* is the actor from the existing pause-lifetime grip. The grip actor will reply:
527
528
```
529
{ "from":<gripActor>, "threadGrip":<threadGrip> }
530
```
531
532
where *threadGrip* is a new grip on the same object, but whose actor is parented by the thread actor, not the pause actor.
533
534
The client can release a thread-lifetime grip by sending the grip actor a request of the form:
535
536
```
537
{ "to":<gripActor>, "type":"release" }
538
```
539
540
The grip actor will reply, simply:
541
542
```
543
{ "from":<gripActor> }
544
```
545
546
This closes the grip actor. The `"release"` packet may only be sent to thread-lifetime grip actors; if a pause-lifetime grip actor receives a `"release"` packet, it sends an error reply of the form:
547
548
```
549
{ "from":<gripActor>, "error":"notReleasable", "message":<message> }
550
```
551
552
where each *gripActor* is the name of a child of *thread* that should be freed. The thread actor will reply, simply:
553
554
```
555
{ "from":<thread> }
556
```
557
558
Regardless of the lifetime of a grip, the client may only send messages to object grip actors while the thread to which they belong is paused; the client's interaction with mutable values cannot take place concurrently with the thread.
559
560
### Completion Values
561
562
Some packets describe the way a stack frame's execution completed using a **completion value**, which takes one of the following forms:
563
564
```
565
{ "return":<grip> }
566
```
567
568
This indicates that the frame completed normally, returning the value given by *grip*.
569
570
```
571
{ "throw":<grip> }
572
```
573
574
This indicates that the frame threw an exception; *grip* is the exception value thrown.
575
576
```
577
{ "terminated":true }
578
```
579
580
This indicates that the frame's execution was terminated, as by a "slow script" dialog box or running out of memory.
581
582
### Source Locations
583
584
Many packets refer to particular locations in source code: breakpoint requests specify where the breakpoint should be set; stack frames show the current point of execution; and so on.
585
586
Descriptions of source code locations (written as *location* in packet descriptions) can take one of the following forms:
587
588
```
589
{ "url":<url>, "line":<line>, "column":<column> }
590
```
591
592
This refers to line *line*, column *column* of the source code loaded from *url*. Line and column numbers start with 1. If *column* or *line* are omitted, they default to 1.
593
594
```
595
{ "eval":<location>, "id":<id>, "line":<line>, "column":<column> }
596
```
597
598
This refers to line *line*, column *column* of the source code passed to the call to eval at *location*. To distinguish the different texts passed to eval, each is assigned a unique integer, *id*.
599
600
```
601
{ "function":<location>, "id":<id>, "line":<line>, "column":<column> }
602
```
603
604
This refers to line *line*, column *column* of the source code passed to the call to the `Function` constructor at *location*. To distinguish the different texts passed to the `Function` constructor, each is assigned a unique integer, *id*.
605
606
As indicated, locations can be nested. A location like this one:
607
608
```
609
{ "eval":{ "eval":{ "url":"file:///home/example/sample.js", "line":20 }
610
"id":300, "line":30 }
611
"id":400, "line":40 }
612
```
613
614
refers to line 40 of the code passed to the call to eval occurring on line 30 of the code passed to the call to eval on line 20 of `file:///home/example/sample.js`.
615
616
## The Root Actor
617
618
When the connection to the server is opened, the root actor opens the conversation with the following packet:
619
620
```
621
{ "from":"root", "applicationType":<appType>, "traits":<traits>, ...}
622
```
623
624
The root actor's name is always `"root"`. *appType* is a string indicating what sort of program the server represents. There may be more properties present, depending on *appType*.
625
626
*traits* is an object describing protocol variants this server supports that are not convenient for the client to detect otherwise. The property names present indicate what traits the server has; the properties' values depend on their names. If *traits* would have no properties, the `"traits"` property of the packet may be omitted altogether. This version of the protocol defines no traits, so if the `"traits"` property is present at all, its value must be an object with no properties, `{}`.
627
628
For web browsers, the introductory packet should have the following form:
629
630
```
631
{ "from":"root", "applicationType":"browser", "traits":<traits> }
632
```
633
634
### Listing Browser Tabs
635
636
To get a list of the tabs currently present in a browser, a client sends the root actor a request of the form:
637
638
```
639
{ "to":"root", "type":"listTabs" }
640
```
641
642
The root actor replies:
643
644
```
645
{ "from":"root", "tabs":[<tab>, ...], "selected":<selected> }
646
```
647
648
where each *tab* describes a single open tab, and *selected* is the index in the array of tabs of the currently selected tab. This form may have other properties describing other global actors; for one example, see [Chrome Debugging](#chrome-debugging).
649
650
Each *tab* has the form:
651
652
```
653
{ "actor":<targetActor>, "title":<title>, "url":<URL> }
654
```
655
656
where *targetActor* is the name of an actor representing the tab, and *title* and *URL* are the title and URL of the web page currently visible in that tab. This form may have other properties describing other tab-specific actors.
657
658
To attach to a *targetActor*, a client sends a message of the form:
659
660
```
661
{ "to":<targetActor>, "type":"attach" }
662
```
663
664
The target actor replies:
665
666
```
667
{ "from":<targetActor>, "type":"tabAttached", "threadActor":<tabThreadActor> }
668
```
669
670
where *tabThreadActor* is the name of a thread-like actor representing the tab's current content. If the user navigates the tab, *tabThreadActor* switches to the new content; we do not create a separate thread-like actor each page the tab visits.
671
672
If the user closes the tab before the client attaches to it, *targetActor* replies:
673
674
```
675
{ "from":<targetActor>, "type":"exited" }
676
```
677
678
When the client is no longer interested in interacting with the tab, the client can request:
679
680
```
681
{ "to":<targetActor>, "type":"detach" }
682
```
683
684
The *targetActor* replies:
685
686
```
687
{ "from":<targetActor>, "type":"detached" }
688
```
689
690
If the client was not already attached to *targetActor*, *targetActor* sends an error reply of the form:
691
692
```
693
{ "from":<targetActor>, "error":"wrongState" }
694
```
695
696
While the client is attached, *targetActor* sends notifications to the client whenever the user navigates the tab to a new page. When navigation begins, *targetActor* sends a packet of the form:
697
698
```
699
{ "from":<targetActor>, "type":"tabNavigated", "state":"start",
700
"url":<newURL> }
701
```
702
703
This indicates that the tab has begun navigating to *newURL*; JavaScript execution in the tab's prior page is suspended. When navigation is complete, *targetActor* sends a packet of the form:
704
705
```
706
{ "from":<targetActor>, "type":"tabNavigated", "state":"stop",
707
"url":<newURL>, "title":<newTitle> }
708
```
709
710
where *newURL* and *newTitle* are the URL and title of the page the tab is now showing. The *tabThreadActor* given in the response to the original `"attach"` packet is now debugging the new page's code.
711
712
If the user closes a tab to which the client is attached, its *targetActor* sends a notification packet of the form:
713
714
```
715
{ "from":<targetActor>, "type":"tabDetached" }
716
```
717
718
The client is now detached from the tab.
719
720
### Chrome Debugging
721
722
If the server supports debugging chrome code, the root actor's reply to a `"listTabs"` request includes a property named `"chromeDebugger"`, whose value is the name of a thread-like actor to which the client can attach to debug chrome code.
723
724
## Interacting with Thread-Like Actors
725
726
Actors representing independent threads of JavaScript execution, like browsing contexts and web workers, are collectively known as "threads". Interactions with actors representing threads follow a more complicated communication pattern.
727
728
A thread is always in one of the following states:
729
730
* **Detached**: the thread is running freely, and not presently interacting with the debugger. Detached threads run, encounter errors, and exit without exchanging any sort of messages with the debugger. A debugger can attach to a thread, putting it in the **Paused** state. Or, a detached thread may exit on its own, entering the **Exited** state.
731
732
* **Running**: the thread is running under the debugger's observation, executing JavaScript code or possibly blocked waiting for input. It will report exceptions, breakpoint hits, watchpoint hits, and other interesting events to the client, and enter the **Paused** state. The debugger can also interrupt a running thread; this elicits a response and puts the thread in the **Paused** state. A running thread may also exit, entering the **Exited** state.
733
734
* **Paused**: the thread has reported a pause to the client and is awaiting further instructions. In this state, a thread can accept requests and send replies. If the client asks the thread to continue or step, it returns to the **Running** state. If the client detaches from the thread, it returns to the **Detached** state.
735
736
* **Exited**: the thread has ceased execution, and will disappear. The resources of the underlying thread may have been freed; this state merely indicates that the actor's name is not yet available for reuse. When the actor receives a "release" packet, the name may be reused.
737
738
![Thread states](../resources/thread-states.png)
739
740
These interactions are meant to have certain properties:
741
742
* At no point may either client or server send an unbounded number of packets without receiving a packet from its counterpart. This avoids deadlock without requiring either side to buffer an arbitrary number of packets per actor.
743
* In states where a transition can be initiated by either the debugger or the thread, it is always clear to the debugger which state the thread actually entered, and for what reason.<br>For example, if the debugger interrupts a running thread, it cannot be sure whether the thread stopped because of the interruption, paused of its own accord (to report a watchpoint hit, say), or exited. However, the next packet the debugger receives will either be "paused", or "exited", resolving the ambiguity.<br>Similarly, when the debugger attaches to a thread, it cannot be sure whether it has succeeded in attaching to the thread, or whether the thread exited before the "attach" packet arrived. However, in either case the debugger can expect a disambiguating response: if the attach succeeded, it receives an "attached" packet; and in the second case, it receives an "exit" packet.<br>To support this property, the thread ignores certain debugger packets in some states (the "interrupt" packet in the **Paused** and **Exited** states, for example). These cases all handle situations where the ignored packet was preempted by some thread action.
744
745
Note that the rules here apply to the client's interactions with each thread actor separately. A client may send an "interrupt" to one thread actor while awaiting a reply to a request sent to a different thread actor.
746
747
*TODO: What about user selecting nodes in displayed content? Should those be eventy things the client can receive in the "paused" state? What does that mean for the "request"/"reply" pattern?*
748
749
### Attaching To a Thread
750
751
To attach to a thread, the client sends a packet of the form:
752
753
```
754
{ "to":<thread>, "type":"attach" }
755
```
756
757
Here, *thread* is the actor representing the thread, perhaps a browsing context from a "listContexts" reply. This packet causes the thread to pause its execution, if it does not exit of its own accord first. The thread responds in one of two ways:
758
759
```
760
{ "from":<thread>, "type":"paused", "why":{ "type":"attached" }, ... }
761
```
762
763
The thread is now in the **Paused** state, because the client has attached to it. The actor name *thread* remains valid until the client detaches from the thread or acknowledges a thread exit. This is an ordinary `"paused"` packet, whose form and additional properties are as described in [Thread Pauses](#thread-pauses), below.
764
765
```
766
{ "from":<thread>, "type":"exited" }
767
```
768
769
This indicates that the thread exited on its own before receiving the "attach" packet. The thread is now in the **Exited** state. The client should follow by sending a "release" packet; see [Exiting Threads](#exiting-threads), below.
770
771
If the client sends an `"attach"` packet to a thread that is not in the **Detached** or **Exited** state, the actor sends an error reply of the form:
772
773
```
774
{ "from":<thread>, "error":"wrongState", "message":<message> }
775
```
776
777
where *message* details which state the thread was in instead (to make debugging debuggers easier). In this case, the thread's state is unaffected.
778
779
### Detaching From a Thread
780
781
To detach from a thread, the client sends a packet of the form:
782
783
```
784
{ "to":<thread>, "type":"detach" }
785
```
786
787
The thread responds in one of three ways:
788
789
```
790
{ "from":<thread>, "type":"detached" }
791
```
792
793
This indicates that the client has detached from the thread. The thread is now in the **Detached** state: it can run freely, and no longer reports events to the client. Communications with *thread* are closed, and the actor name is available for reuse. If the thread had been in the **Paused** state, the pause actor is closed (because the pause actor is a child of *thread*).
794
795
```
796
{ "from":<thread>, "type":"paused", ... }
797
{ "from":<thread>, "type":"detached" }
798
```
799
800
This series of packets indicates that the thread paused of its own accord (for the reason given by the additional properties of the "paused" packet), and only then received the "detach" packet. As above, this indicates that the thread is in the **Detached** state, the just-created pause actor is closed, and the actor name is available for reuse.
801
802
```
803
{ "from":<thread>, "type":"exited" }
804
```
805
806
This indicates that the thread exited on its own before receiving the "detach" packet. The client should follow by sending a "release" packet; see [Exiting Threads](#exiting-threads), below.
807
808
Detaching from a thread causes all breakpoints, watchpoints, and other debugging-related state to be forgotten.
809
810
If the client sends a `"detach"` packet to a thread that is not in the **Running**, **Paused**, or **Exited** state, the actor sends an error reply of the form:
811
812
```
813
{ "from":<thread>, "error":"wrongState", "message":<message> }
814
```
815
816
where *message* details which state the thread was in instead (to make debugging debuggers easier). In this case, the thread's state is unaffected.
817
818
### Running Threads
819
820
Once the client has attached to a thread, it is in the **Running** state. In this state, four things can happen:
821
822
* The thread can hit a breakpoint or watchpoint, or encounter some other condition of interest to the client.
823
* The thread can exit.
824
* The client can detach from the thread.
825
* The client can interrupt the running thread.
826
827
Note that a client action can occur simultaneously with a thread action. The protocol is designed to avoid ambiguities when both client and thread act simultaneously.
828
829
### Thread Pauses
830
831
If the thread pauses to report an interesting event to the client, it sends a packet of the form:
832
833
```
834
{ "from":<thread>, "type":"paused", "actor":<pauseActor>, "why":<reason>,
835
"currentFrame":<frame>, "poppedFrames":[<poppedFrame>...] }
836
```
837
838
This indicates that the thread has entered the **Paused** state, and explains where and why.
839
840
*PauseActor* is a "pause actor", representing this specific pause of the thread; it lives until the thread next leaves the **Paused** state. The pause actor parents actors referring to values and other entities uncovered during this pause; when the thread resumes, those actors are automatically closed. This relieves the client from the responsibility to explicitly close every actor mentioned during the pause.
841
842
Since actors in value grips are parented by the pause actor, this means that those grips become invalid when the thread resumes, or is detached from; it is not possible to take a grip from one pause and use it in the next. To create a grip that remains valid between pauses, see [Grip Lifetimes](#grip-lifetimes).
843
844
The *currentFrame* value describes the top frame on the JavaScript stack; see [Listing Stack Frames](#listing-stack-frames), below.
845
846
The `"poppedFrames"` property is an array of frame actor names, listing the actors for all frames that were live as of the last pause, but have since been popped. If no frames have been popped, or if this is the first pause for this thread, then this property's value is the empty array.
847
848
The *reason* value describes why the thread paused. It has one of the following forms:
849
850
```
851
{ "type":"attached" }
852
```
853
854
The thread paused because the client attached to it.
855
856
```
857
{ "type":"interrupted" }
858
```
859
860
The thread stopped because it received an "interrupt" packet from the client.
861
862
```
863
{ "type":"resumeLimit" }
864
```
865
866
The client resumed the thread with a `"resume"` packet that included a `resumeLimit` property, and the thread paused because the given *limit* was met. Execution remains in the frame the thread was resumed in, and that frame is not about to be popped.
867
868
```
869
{ "type":"resumeLimit", "frameFinished":<completion> }
870
```
871
872
The client resumed the thread with a `"resume"` packet that included a `resumeLimit` property, and the thread paused because the frame is about to be popped. *Completion* is a [completion value](#completion-values) describing how the frame's execution ended. The frame being popped is still the top frame on the stack, but subsequent `"resume"` operations will run in the calling frame.
873
874
```
875
{ "type":"debuggerStatement" }
876
```
877
878
The thread stopped because it executed a JavaScript "debugger" statement.
879
880
```
881
{ "type":"breakpoint", "actors":[<breakpointActor>...] }
882
```
883
884
The thread stopped at the breakpoints represented by the given actors.
885
886
```
887
{ "type":"watchpoint", "actors":[<watchpointActor>...] }
888
```
889
890
The thread stopped at the watchpoints represented by the given actors.
891
892
*TODO: This should provide more details about the watchpoint in the packet, instead of incurring another round-trip before we can display anything helpful.*
893
894
```
895
{ "type":"clientEvaluated", "frameFinished":<completion> }
896
```
897
898
The expression given in the client's prior `clientEvaluate` command has completed execution; *completion* is a [completion value](#completion-values) describing how it completed. The frame created for the `clientEvaluate` resumption has been popped from the stack. See [Evaluating Source-Language Expressions](#evaluating-source-language-expressions) for details.
899
900
### Resuming a Thread
901
902
If a thread is in the **Paused** state, the client can resume it by sending a packet of the following form:
903
904
```
905
{ "to":<thread>, "type":"resume" }
906
```
907
908
This puts the thread in the **Running** state. The thread will pause again for breakpoint hits, watchpoint hits, throw watches, frame pop watches, and other standing pause requests.
909
910
To step a thread's execution, the client can send a packet of the form:
911
912
```
913
{ "to":<thread>, "type":"resume", "resumeLimit":<limit> }
914
```
915
916
*Limit* must have one of the following forms:
917
918
```
919
{ "type":"next" }
920
```
921
922
The thread should pause:
923
924
* just before the current frame is popped, whether by throwing an exception or returning a value; or
925
* when control in the current frame reaches a different statement than the one it is currently at.
926
927
Note that execution in frames younger than the current frame never meets these conditions, so a `"next"` limit steps over calls, generator-iterator invocations, and so on.
928
929
```
930
{ "type":"step" }
931
```
932
933
The thread should pause:
934
935
* just before the current frame is popped, whether by throwing an exception or returning a value; or
936
* just after a new frame is pushed; or
937
* when control in the current frame reaches a different statement than the one it is currently at.
938
939
This is the same as `"next"`, except that it steps into calls.
940
941
To resume the thread but have it stop when the current frame is about to be popped, the client can send a packet of the form:
942
943
```
944
{ "to":<thread>, "type":"resume", "resumeLimit":{ "type":"finish" } }
945
```
946
947
Here, the thread should pause just before the current frame is popped, whether by throwing an exception, returning a value, or being terminated.
948
949
When a thread pauses because a limit was reached, the "paused" packet's *reason* will have a type of `"resumeLimit"`.
950
951
A resume limit applies only to the current resumption; once the thread pauses, whether because the limit was reached or some other event occurred&mdash;a breakpoint hit, for example&mdash;the resume limit is no longer in effect.
952
953
If no `"resumeLimit"` property appears in the `"resume"` packet, then the thread should run until some standing pause condition is met (a breakpoint is hit; a watchpoint triggers; or the like).
954
955
To force the current frame to end execution immediately, the client can send a packet of the form:
956
957
```
958
{ "to":<thread>, "type":"resume", "forceCompletion":<completion> }
959
```
960
961
where *completion* is a [completion value](#completion-values) indicating whether the frame should return a value, throw an exception, or be terminated. Execution resumes in the current frame's caller, in the manner appropriate for *completion*.
962
963
To request that execution pause when an exception is thrown, the client may send a request of the form:
964
965
```
966
{ "to":<thread>, "type":"resume", "pauseOnExceptions": true }
967
```
968
969
If `pauseOnExceptions` has the value `false` or is omitted, execution will continue in the face of thrown exceptions. When a thread pauses because an exception was thrown, the "paused" packet's *reason* will have the following form:
970
971
```
972
{ "type":"exception", "exception":<exception> }
973
```
974
975
where *exception* is a grip on the exception object.
976
977
To request that execution pause on a DOM event, the client may send a request of the form:
978
979
If a `"forceCompletion"` property is present in a `"resume"` packet, along with `"resumeLimit"`, or `"pauseOnExceptions"`, the thread will respond with an error:
980
981
```
982
{ "from":<thread>, "error":"badParameterType", "message":<message> }
983
```
984
985
A `"resume"` packet closes the pause actor the client provided in the "paused" packet that began the pause.
986
987
If the client sends a `"resume"` packet to a thread that is not in the **Paused** state, the actor sends an error reply of the form:
988
989
```
990
{ "from":<thread>, "error":"wrongState", "message":<message> }
991
```
992
993
where *message* details which state the thread was in instead (to make debugging debuggers easier). In this case, the thread's state is unaffected.
994
995
### Interrupting a Thread
996
997
If a thread is in the **Running** state, the client can cause it to pause where it is by sending a packet of the following form:
998
999
```
1000
{ "to":<thread>, "type":"interrupt" }
1001
```
1002
1003
The thread responds in one of two ways:
1004
1005
```
1006
{ "from":<thread>, "type":"paused", "why":<reason>, ... }
1007
```
1008
1009
This indicates that the thread stopped, and is now in the **Paused** state. If *reason* is `{ "type":"interrupted" }`, then the thread paused due to the client's *interrupt* packet. Otherwise, the thread paused of its own accord before receiving the *interrupt* packet, and will ignore the *interrupt* packet when it receives it. In either case, this is an ordinary `"paused"` packet, whose form and additional properties are as described in [Thread Pauses](#thread-pauses), above.
1010
1011
```
1012
{ "from":<thread>, "type":"exited" }
1013
```
1014
1015
This indicates that the thread exited before receiving the client's *interrupt* packet, and is now in the **Exited** state. See [Exiting Threads](#exiting-threads), below.
1016
1017
If the client sends an `"interrupt"` packet to a thread that is not in the **Running**, **Paused**, or **Exited** state, the actor sends an error reply of the form:
1018
1019
```
1020
{ "from":<thread>, "error":"wrongState", "message":<message> }
1021
```
1022
1023
where *message* details which state the thread was in instead (to make debugging debuggers easier). In this case, the thread's state is unaffected.
1024
1025
### Exiting Threads
1026
1027
When a thread in the **Running** state exits, it sends a packet of the following form:
1028
1029
```
1030
{ "from":<thread>, "type":"exited" }
1031
```
1032
1033
At this point, the thread can no longer be manipulated by the client, and most of the thread's resources may be freed; however, the thread actor name must remain alive, to handle stray `interrupt` and `detach` packets. To allow the last trace of the thread to be freed, the client should send a packet of the following form:
1034
1035
```
1036
{ "to":<thread>, "type":"release" }
1037
```
1038
1039
This acknowledges the exit and allows the thread actor name, *thread*, to be reused for other actors.
1040
1041
## Inspecting Paused Threads
1042
1043
When a thread is in the **Paused** state, the debugger can make requests to inspect its stack, lexical environment, and values.
1044
1045
Only those packets explicitly defined to do so can cause the thread to resume execution. JavaScript features like getters, setters, and proxies, which could normally lead inspection operations like enumerating properties and examining their values to run arbitrary JavaScript code, are disabled while the thread is paused. If a given protocol request is not defined to let the thread run, but carrying out the requested operation would normally cause it to do so&mdash;say, fetching the value of a getter property&mdash;the actor sends an error reply of the form:
1046
1047
```
1048
{ "from":<actor>, "error":"threadWouldRun", "message":<message>, "cause":<cause> }
1049
```
1050
1051
where *message* is text that could be displayed to users explaining why the operation could not be carried out. *Cause* is one of the following strings:
1052
1053
| *cause* value | meaning |
1054
|:-------------:|:------------------------------------------------------------------------:|
1055
| "proxy" | Carrying out the operation would cause a proxy handler to run. |
1056
| "getter" | Carrying out the operation would cause an object property getter to run. |
1057
| "setter" | Carrying out the operation would cause an object property setter to run. |
1058
1059
(Taken together, the `"threadWouldRun"` error name and the *cause* value should allow the debugger to present an appropriately localized error message.)
1060
1061
### Loading Script Sources
1062
1063
To get a snapshot of all sources currently loaded by the thread actor, the client can send the following packet:
1064
1065
```
1066
{ to: <threadActorID>, type: "sources" }
1067
```
1068
1069
The response packet has the form:
1070
1071
```
1072
{ from: <threadActorID>, sources: [<sourceForm1>, <sourceForm2>, ..., <sourceFormN>] }
1073
```
1074
1075
Where each *sourceForm* has the following form:
1076
1077
```
1078
{ actor: <sourceActorID>,
1079
url: <sourceURL>,
1080
isBlackBoxed: <isBlackBoxed> }
1081
```
1082
1083
* *sourceActorID* is the source actor's id
1084
* *sourceURL* is the URL of the source represented by the source actor
1085
* *isBlackBoxed* is a boolean specifying whether the source actor's 'black-boxed' flag is set. See [Black Boxing Sources](#black-boxing-sources).
1086
1087
Each source actor exists throughout the thread's whole lifetime.
1088
1089
To get the contents of a source, send the corresponding source actor the following packet:
1090
1091
```
1092
{ to: <sourceActorID>, type: "source" }
1093
```
1094
1095
And the source actor replies with a packet of the following form:
1096
1097
```
1098
{ from: <sourceActorID>, source: <contentsOfSource> }
1099
```
1100
1101
where *contentsOfSource* is a grip representing the string of source code: either a JSON string, or a long string grip. (See [Grips](#grips) for a description of long string grips.)
1102
1103
#### Black-Boxing Sources
1104
1105
When debugging a web application that uses large off-the-shelf JavaScript libraries, it may help the developer focus on their own code to treat such libraries as "black boxes", whose internal details are omitted or simplified in the user interface. For example, the user interface could display a sub-chain of stack frames within a black-boxed library as a single element; breakpoints set in a black-boxed library could be disabled; and so on.
1106
1107
Each source actor has a 'black-boxed' flag, and understands requests to set and clear the flag. When a source actor is black-boxed, the debugger does not pause when it hits breakpoints or `debugger` statements inside that source. If pausing on exceptions is enabled and an exception is thrown inside a black-boxed source, the debugger does not pause until the stack has unwound to a frame in a source that is not black-boxed.
1108
1109
Thread actors still list black-boxed source actors in `"sources"` replies; and include stack frames running black-boxed code in `"frames"` requests. However, each *sourceForm* includes an `"isBlackBoxed"` property, giving the client all the information it needs to implement the black-boxing behavior in the user interface.
1110
1111
To set a source actor's 'black-boxed' flag:
1112
1113
```
1114
{ "to": <sourceActor>, "type": "blackbox" }
1115
```
1116
1117
The *sourceActor* responds with a blank response on success:
1118
1119
```
1120
{ "from": <sourceActor> }
1121
```
1122
1123
Or an error response on failure:
1124
1125
```
1126
{ "from": <sourceActor>, "error": <reason> }
1127
```
1128
1129
To clear a source actor's 'black-boxed' flag:
1130
1131
```
1132
{ "to": <sourceActor>, "type": "unblackbox" }
1133
```
1134
1135
And once again, the *sourceActor* responds with a blank response on success:
1136
1137
```
1138
{ "from": <sourceActor> }
1139
```
1140
1141
Or an error response on failure:
1142
1143
```
1144
{ "from": <sourceActor>, "error": <reason> }
1145
```
1146
1147
### Listing Stack Frames
1148
1149
To inspect the thread's JavaScript stack, the client can send the following request:
1150
1151
```
1152
{ "to":<thread>, "type":"frames", "start":<start>, "count":<count> }
1153
```
1154
1155
The `start` and `count` properties are optional. If present, *start* gives the number of the youngest stack frame the reply should describe, where the youngest frame on the stack is frame number zero; if absent, *start* is taken to be zero. If present, *count* specifies the maximum number of frames the reply should describe; if absent, it is taken to be infinity. (Clients should probably avoid sending `frames` requests with no *count*, to avoid being flooded by frames from unbounded recursion.)
1156
1157
The thread replies as follows:
1158
1159
```
1160
{ "from":<thread>, "frames":[<frame> ...] }
1161
```
1162
1163
where each *frame* has the form:
1164
1165
```
1166
{ "actor": <actor>,
1167
"depth": <depth>,
1168
"type": <type>,
1169
"this": <this>,
1170
... }
1171
```
1172
1173
where:
1174
1175
* *actor* is the name of an actor representing this frame;
1176
* *depth* is the number of this frame, starting with zero for the youngest frame on the stack;
1177
* *type* is a string indicating what sort of frame this is; and
1178
* *this* is a grip on the value of `this` for this call.
1179
1180
The frame may have other properties, depending on *type*.
1181
1182
All actors mentioned in the frame or grips appearing in the frame (*actor*, *callee*, *environment*, and so on) are parented by the thread actor.
1183
1184
#### Global Code Frames
1185
1186
A frame for global code has the form:
1187
1188
```
1189
{ "actor":<actor>,
1190
"depth":<depth>,
1191
"type":"global",
1192
"this":<this>,
1193
"where":<location>,
1194
"source":<source>,
1195
"environment":<environment> }
1196
```
1197
1198
where:
1199
1200
* *location* is the source location of the current point of execution in the global code (see [Source Locations](#source-locations));
1201
* *environment* is a value representing the lexical environment of the current point of execution (see [Lexical Environments](#lexical-environments));
1202
* *source* is a source form as described in [Loading Script Sources](#loading-script-sources)
1203
1204
and other properties are as above.
1205
1206
#### Function Call Frames
1207
1208
A frame for an ordinary JavaScript function call has the form:
1209
1210
```
1211
{ "actor":<actor>, "depth":<depth>, "type":"call", "this":<this>,
1212
"where":<location>, "environment":<environment>,
1213
"callee":<callee>, "arguments":<arguments> }
1214
```
1215
1216
where:
1217
1218
* *callee* is a grip on the function value being called;
1219
* *arguments* is an array of grips on the actual values passed to the function;
1220
1221
and other properties are as above.
1222
1223
If the callee is a host function, or a function scoped to some global other than the one to which we are attached, the `"where"` and `"environment"` properties are absent.
1224
1225
The argument list may be incomplete or inaccurate, for various reasons. If the program has assigned to its formal parameters, the original values passed may have been lost, and compiler optimizations may drop some argument values.
1226
1227
#### Eval Frames
1228
1229
A frame for a call to `eval` has the form:
1230
1231
```
1232
{ "actor":<actor>, "depth":<depth>, "type":"eval", "this":<this>,
1233
"where":<location>, "environment":<environment> }
1234
```
1235
1236
where the properties are as defined above.
1237
1238
#### Client Evaluation Frames
1239
1240
When the client evaluates an expression with an `clientEvaluate` packet, the evaluation appears on the stack as a special kind of frame, of the form:
1241
1242
```
1243
{ "actor":<actor>, "depth":<depth>, "type":"clientEvaluate", "this":<this>,
1244
"where":<location>, "environment":<environment> }
1245
```
1246
1247
where the properties are as defined above. In this case, *where* will be a location inside the expression provided by the debugger.
1248
1249
### Popping Stack Frames
1250
1251
The client can remove frames from the stack by sending a request of the form:
1252
1253
```
1254
{ "to":<frameActor>, "type":"pop", "completionValue":<completion> }
1255
```
1256
1257
where *frameActor* is the actor representing the stack frame to pop, and *completion* is a [completion value](#completion-values) describing how the frame should appear to have finished execution. All younger stack frames are also popped. The thread remains paused. The frame actor will reply:
1258
1259
```
1260
{ "from":<frameActor>, "watches":[<watchActor> ...] }
1261
```
1262
1263
where each *watchActor* is the name of a frame pop watch actor that has been triggered in the process of popping the given frame. If no frame pop watches are triggered, the `watches` property may be omitted.
1264
1265
*TODO: specify the error to return if the frame cannot be popped --- can host (C++) function frames be popped?*
1266
1267
### Evaluating Source-Language Expressions
1268
1269
To evaluate a source-language expression in a thread, the client sends a specialized `"resume"` packet of the form:
1270
1271
```
1272
{ "to":<thread>, "type":"clientEvaluate", "expression":<expr>, "frame":<frame> }
1273
```
1274
1275
This resumes the thread just as an ordinary `"resume"` packet does, but, rather than continuing execution where the pause took place, has the thread begin evaluation of the source-language expression given by *expr*, a string. The evaluation takes place in a new [Client Evaluation Frame](#client-evaluation-frames), pushed on top of *thread*'s current stack, using the environment of *frame*. *Frame* must be a live actor for one of *thread*'s frames, and the given frame must be one from which we can retrieve a lexical environment; that is, it must not be the frame for a call to a non-debuggee function. When evaluation of *expr* completes, the client will report a `clientEvaluate` pause containing the expression's value.
1276
1277
If evaluating *expr* completes abruptly, this outcome is still reported via an `clientEvaluated` pause, so it is not necessary for the client to take explicit steps to catch exceptions thrown by the expression.
1278
1279
If *frame* is not the name of an actor for a frame currently on *thread*'s stack, the thread actor sends a reply of the form:
1280
1281
```
1282
{ "from":<thread>, "error":"unknownFrame", "message":<message> }
1283
```
1284
1285
where *message* provides any details that would be helpful to the debugger developers. In this case, the thread's state is unaffected.
1286
1287
If *frame* is not a frame whose environment we can access, the thread actor sends an error reply of the form:
1288
1289
```
1290
{ "from":<thread>, "error":"notDebuggee", "message":<message> }
1291
```
1292
1293
where *message* provides further appropriate details.
1294
1295
If the client sends a `"clientEvaluate"` packet to a thread that is not in the **Paused** state, the actor sends an error reply of the form:
1296
1297
```
1298
{ "from":<thread>, "error":"wrongState", "message":<message> }
1299
```
1300
1301
where *message* details which state the thread was in instead (to make debugging debuggers easier). In this case, the thread's state is unaffected.
1302
1303
*TODO: evaluate with given grips bound to given identifiers*
1304
1305
## Lexical Environments
1306
1307
A lexical environment (written as *environment* in packet descriptions) records the identifier bindings visible at a particular point in the program. An environment has one of the following forms:
1308
1309
```
1310
{ "type":"object", "actor":<actor>, "object":<object>, "parent":<parentEnvironment> }
1311
```
1312
1313
This represents a scope chain element whose identifier bindings reflect the properties of *object* (a grip). This could be the global object (`window` in a browser), or a DOM element (for event handler content attributes, which have the input element, form, and document on their scope chain along with the `window`).
1314
1315
*Actor* is the name of an actor representing this lexical environment. The requests it can answer are described below.
1316
1317
*ParentEnvironment* is a lexical environment describing the next enclosing environment; the `parent` property is omitted on the outermost environment.
1318
1319
```
1320
{ "type":"function", "actor":<actor>, "function":<function>,
1321
"bindings":<bindings>, "parent":<parentEnvironment> }
1322
```
1323
1324
This represents the variable environment created by a call to *function* (a grip). *Bindings* describes the bindings in scope, including the function's arguments, the `arguments` object, and local `var` and function bindings; its form is described in detail below. The other properties are as described above.
1325
1326
```
1327
{ "type":"with", "actor":<actor>, "object":<object>, "parent":<parentEnvironment> }
1328
```
1329
1330
This represents an environment introduced by a `with` statement whose operand is *object* (a grip). The other properties are as described above.
1331
1332
```
1333
{ "type":"block", "actor":<actor>, "bindings":<bindings>, "parent":<parentEnvironment> }
1334
```
1335
1336
This represents an environment introduced by a `let` block, `for-in` statement, `catch` block, or the like. The properties are as described above.
1337
1338
A *bindings* value has the form:
1339
1340
```
1341
{ "arguments":[ { name:<descriptor> }, ... ],
1342
"variables":{ name:<descriptor>, ... } }
1343
```
1344
1345
Each *name* is the name of a bound identifier, as a string. Each *descriptor* is a [property descriptor](#property-descriptors) for the variable, presenting the variable's value as the descriptor's `"value"` property, and the variable's mutability as the descriptor's `"writable"` property. The descriptor's `"configurable"` property reflects whether the environment supports deleting and adding variables. Each descriptor's `"enumerable"` property is `true`.
1346
1347
The `"arguments"` list appears only in bindings for `"function"` environments. It lists the arguments in the order they appear in the function's definition. (The same name may appear several times in the list, as permitted by JavaScript; the name's last appearance is the one in scope in the function.)
1348
1349
Note that language implementations may omit some environment records from a function's scope if it can determine that the function would not use them. This means that it may be impossible for a debugger to find all the variables that ought to be in scope.
1350
1351
To fully enumerate the bindings introduced by any lexical environment, the client can send a request of the following form to the environment's actor:
1352
1353
```
1354
{ "to":<envActor>, "type":"bindings" }
1355
```
1356
1357
The actor will reply as follows:
1358
1359
```
1360
{ "from":<envActor>, "bindings":<bindings> }
1361
```
1362
1363
Note that this request elicits a `"threadWouldRun"` error reply when *envActor* refers to an object environment whose object is a proxy.
1364
1365
To change the value of a variable bound in a particular lexical environment, the client can send a request to the environment's actor:
1366
1367
```
1368
{ "to":<envActor>, "type":"assign", "name":<name>, "value":<value> }
1369
```
1370
1371
This changes the value of the identifier whose name is *name* (a string) to that represented by *value* (a grip). The actor will reply as follows, simply:
1372
1373
```
1374
{ "from":<envActor> }
1375
```
1376
1377
If the named identifier is immutable, the actor will send an error reply of the form:
1378
1379
```
1380
{ "from":<envActor>, "error":"immutableBinding", "message":<message> }
1381
```
1382
1383
If *envActor* refers to an object environment whose object is a proxy, or whose property named *name* has a setter function, this request elicits a `"threadWouldRun"` error reply.
1384
1385
### Lexical Environment Examples
1386
1387
For example, if we have the following JavaScript code:
1388
1389
```
1390
function f(x) {
1391
function g(y) {
1392
var z = "value of z";
1393
alert(x + y);
1394
}
1395
}
1396
```
1397
1398
we set a breakpoint on the line containing the call to `alert`, and then evaluate the expression:
1399
1400
```
1401
f("argument to f")("argument to g")
1402
```
1403
1404
then we would hit that breakpoint, eliciting a packet like the following:
1405
1406
```
1407
{ "from":<thread>, "type":"paused", "actor":<pauseActor>,
1408
"why":{ "type":"breakpoint", "actors":[<breakpointActor>] },
1409
"frame":{ "actor":<frameActor>, "depth":1,
1410
"type":"call", "where":{ "url":"sample.js", "line":3 },
1411
"environment":{ "type":"function", "actor":<gFrameActor>,
1412
"function":{ "type":"object", "class":"Function", "actor":<gActor> },
1413
"functionName":"g",
1414
"bindings":{ arguments: [ { "y": { "value":"argument to g", "configurable":"false",
1415
"writable":true, "enumerable":true } } ] },
1416
"parent":{ "type":"function", "actor":<fFrameActor>,
1417
"function":{ "type":"object", "class":"Function", "actor":<fActor> },
1418
"functionName":"f",
1419
"bindings": { arguments: [ { "x": { "value":"argument to f", "configurable":"false",
1420
"writable":true, "enumerable":true } } ],
1421
variables: { "z": { "value":"value of z", "configurable":"false",
1422
"writable":true, "enumerable":true } } },
1423
"parent":{ "type":"object", "actor":<globalCodeActor>,
1424
"object":{ "type":"object", "class":"Global",
1425
"actor":<globalObjectActor> }
1426
}
1427
}
1428
},
1429
"callee":<gActor>, "calleeName":"g",
1430
"this":{ "type":"object", "class":"Function", "actor":<gActor> },
1431
"arguments":["argument to g"]
1432
}
1433
}
1434
```
1435
1436
You can see here the three nested environment forms, starting with the `environment` property of the top stack frame, reported in the pause:
1437
1438
* The first environment form shows the environment record created by the call to `g`, with the string `"argument to g"` passed as the value of `y`.
1439
* Because `g` is nested within `f`, each function object generated for `g` captures the environment of a call to the enclosing function `f`. Thus, the next thing on `g`'s scope chain is an environment form for the call to `f`, where `"argument to f"` was passed as the vale of `x`.
1440
* Because `f` is a top-level function, the (only) function object for `f` closes over the global object. This is the "type":"object" environment shown as the parent of `f`'s environment record.
1441
* Because the global object is at the end of the scope chain, its environment form has no `parent` property.
1442
1443
## Breakpoints
1444
1445
While a thread is paused, a client can set breakpoints in the thread's code by sending requests of the form:
1446
1447
```
1448
{ "to":<thread>, "type":"setBreakpoint", "location":<location> }
1449
```
1450
1451
where *location* is a [source location](#source-locations). If the thread is able to establish a breakpoint at the given location, it replies:
1452
1453
```
1454
{ "from":<thread>, "actor":<actor>, "actualLocation":<actualLocation> }
1455
```
1456
1457
where *actor* is an actor representing the breakpoint (a child of the thread actor), and *actualLocation* is the location at which the breakpoint was really set. If *location* and *actualLocation* are the same, then the `actualLocation` property can be omitted.
1458
1459
If the thread cannot find the script referred to in *location*, it sends an error reply of the form:
1460
1461
```
1462
{ "from":<thread>, "error":"noScript" }
1463
```
1464
1465
If *location* refers to a line and column at which the given script has no program code, and no reasonable alternative location can be chosen (say, by skipping forward), then the thread sends an error reply of the form:
1466
1467
```
1468
{ "from":<thread>, "error":"noCodeAtLineColumn" }
1469
```
1470
1471
To delete a breakpoint, the client can send the breakpoint's actor a message of the form:
1472
1473
```
1474
{ "to":<breakpointActor>, "type":"delete" }
1475
```
1476
1477
to which the breakpoint actor will reply, simply:
1478
1479
```
1480
{ "from":<breakpointActor> }
1481
```
1482
1483
This closes communications with *breakpointActor*.
1484
1485
## Event Listeners
1486
1487
To request a list of all the event listeners and event handlers (see [DOM Event Handlers](https://developer.mozilla.org/docs/Web/Guide/DOM/Events/Event_handlers#Definitions) for definitions of the two terms) attached to the page, the client sends a request of the form:
1488
1489
```
1490
{ "to":<thread>, "type":"eventListeners" }
1491
```
1492
1493
The thread replies with a response of the form:
1494
1495
```
1496
{ "from":<thread>, "listeners":[ <listener>, ... ] }
1497
```
1498
1499
Such requests can be sent when the thread is either paused or running. A *listener* value has the form:
1500
1501
```
1502
{ "node":{ "selector":<node-selector>, "object":<node> },
1503
"type":<type>,
1504
"capturing":<capturing>,
1505
"allowsUntrusted":<allowsUntrusted>,
1506
"inSystemEventGroup":<inSystemEventGroup>,
1507
"isEventHandler":<isEventHandler>,
1508
"function":<function> }
1509
```
1510
1511
The values for these properties are:
1512
1513
***node-selector***
1514
1515
A unique CSS selector of the DOM element on which the event handler is attached, or `"window"` if the handler is attached on the window.
1516
1517
***node***
1518
1519
A grip on the DOM element on which the event handler is attached.
1520
1521
***type***
1522
1523
The type of the DOM event as specified in the DOM specification (see [nsIEventListenerInfo](https://developer.mozilla.org/docs/XPCOM_Interface_Reference/nsIEventListenerInfo#Attributes)).
1524
1525
***capturing***
1526
1527
A boolean flag indicating whether the event listener is in capture mode (see [nsIEventListenerInfo](https://developer.mozilla.org/docs/XPCOM_Interface_Reference/nsIEventListenerInfo#Attributes)).
1528
1529
***allowsUntrusted***
1530
1531
A boolean flag that indicates whether the listener allows untrusted events (see [nsIEventListenerInfo](https://developer.mozilla.org/docs/XPCOM_Interface_Reference/nsIEventListenerInfo#Attributes)).
1532
1533
***inSystemEventGroup***
1534
1535
A boolean flag that indicates whether or not the event listener is in the system event group (see [nsIEventListenerInfo](https://developer.mozilla.org/docs/XPCOM_Interface_Reference/nsIEventListenerInfo#Attributes)).
1536
1537
***isEventHandler***
1538
1539
A boolean flag indicating whether this is an event handler or an event listener (see [DOM Event Handlers](https://developer.mozilla.org/docs/Web/Guide/DOM/Events/Event_handlers#Definitions) for definitions of the two terms). For HTML attribute handlers or assignments to WebIDL properties this flag would be true.
1540
1541
***function***
1542
1543
A grip on the function object.
1544
1545
## Stream Transport
1546
1547
The debugging protocol is specified in terms of packets exchanged between a client and server, where each packet is either a JSON text or a block of bytes (a "bulk data" packet). The protocol does not specify any particular mechanism for carrying packets from one party to the other. Implementations may choose whatever transport they like, as long as packets arrive reliably, undamaged, and in order.
1548
1549
This section describes the Mozilla Remote Debugging Protocol Stream Transport, a transport layer suitable for carrying Mozilla debugging protocol packets over a reliable, ordered byte stream, like a TCP/IP stream or a pipe. Debugger user interfaces can use it to exchange packets with debuggees in other processes (say, for debugging Firefox chrome code), or on other machines (say, for debugging Firefox OS apps running on a phone or tablet).
1550
1551
(The Stream Transport is not the only transport used by Mozilla. For example, when using Firefox's built-in script debugger, the client and server are in the same process, so for efficiency they use a transport that simply exchanges the JavaScript objects corresponding to the JSON texts specified by the protocol, and avoid serializing packets altogether.)
1552
1553
### Packets
1554
1555
Once the underlying byte stream is established, transport participants may immediately begin sending packets, using the forms described here. The transport requires no initial handshake or setup, and no shutdown exchange: the first bytes on the stream in each direction are those of the first packet, if any; the last bytes on the stream in each direction are the final bytes of the last packet sent, if any.
1556
1557
The transport defines two types of packets: JSON and bulk data.
1558
1559
#### JSON Packets
1560
1561
A JSON packet has the form:
1562
1563
```
1564
length:JSON
1565
```
1566
1567
where *length* is a series of decimal ASCII digits, *JSON* is a well-formed JSON text (as defined in [RFC 4627](http://www.ietf.org/rfc/rfc4627.txt)) encoded in UTF-8, and *length*, interpreted as a number, is the length of *JSON* in bytes.
1568
1569
#### Bulk Data Packets
1570
1571
A bulk data packet has the form:
1572
1573
```
1574
bulk actor type length:data
1575
```
1576
1577
where:
1578
1579
* The keyword `bulk` is encoded in ASCII, and the spaces are always exactly one ASCII space
1580
* *actor* is a sequence of Unicode characters, encoded in UTF-8, containing no spaces or colons
1581
* *type* is a sequence of Unicode characters, encoded in UTF-8, containing no spaces or colons
1582
* *length* is a sequence of decimal ASCII digits
1583
* *data* is a sequence of bytes whose length is *length* interpreted as a number
1584
1585
The *actor* field is the name of the actor sending or receiving the packet. (Actors are server-side entities, so if the packet was sent by the client, *actor* names the recipient; and if the packet was sent by the server, *actor* names the sender.) The protocol imposes the same syntactic restrictions on actor names that we require here.
1586
1587
Which actor names are valid at any given point in an exchange is established by the remote debugging protocol.
1588
1589
The *type* field defines the type of the packet, which may be used with the actor name to route the packet to its destination properly. The protocol provides more detail about the type, which remains in effect here.
1590
1591
The content of a bulk data packet is exactly the sequence of bytes appearing as *data*. Data is not UTF-8 text.
1592
1593
### Stream Requirements
1594
1595
The Stream Transport requires the underlying stream to have the following properties:
1596
1597
* It must be **transparent**: each transmitted byte is carried to the recipient without modification. Bytes whose values are ASCII control characters or fall outside the range of ASCII altogether must be carried unchanged; line terminators are left alone.
1598
* It must be **reliable**: every transmitted byte makes it to the recipient, or else the connection is dropped altogether. Errors introduced by hardware, say, must be detected and corrected, or at least reported (and the connection dropped). The Stream Transport includes no checksums of its own; those are the stream's responsibility. (So, for example, a plain serial line is not suitable for use as an underlying stream.)
1599
* It must be **ordered**: bytes are received in the same order they are transmitted, and bytes are not duplicated. (UDP packets, for example, may be duplicated or arrive out of order.)
1600
1601
TCP/IP streams and USB streams meet these requirements.
1602
1603
### Implementation Notes
1604
1605
#### Constant-Overhead Bulk Data
1606
1607
Mozilla added bulk data packets to the protocol to let devices with limited memory upload performance profiling and other large data sets more efficiently. Profiling data sets need to be as large as possible, as larger data sets can cover a longer period of time or more frequent samples. However, converting a large data set to a JavaScript object, converting that object to a JSON text, and sending the text over the connection entails making several temporary complete copies of the data; on small devices, this limits how much data the profiler can collect. Avoiding these temporary copies would allow small devices to collect and transmit larger profile data sets. Since it seemed likely that other sorts of tools would need to exchange large binary blocks efficiently as well, we wanted a solution usable by all protocol participants, rather than one tailored to the profiler's specific case.
1608
1609
In our implementation of this Stream Transport, when a participant wishes to transmit a bulk data packet, it provides the actor name, the type, the data's length in bytes, and a callback function. When the underlying stream is ready to send more data, the transport writes the packet's `bulk actor type length:` header, and then passes the underlying `nsIOutputStream` to the callback, which then writes the packet's data portion directly to the stream. Similarly, when a participant receives a bulk data packet, the transport parses the header, and then passes the actor name, type, and the transport's underlying `nsIInputStream` to a callback function, which consumes the data directly. Thus, while the callback functions may well use fixed-size buffers to send and receive data, the transport imposes no overhead proportional to the full size of the data.