Confirmed users
496
edits
(Add sections on running, pausing, resuming, and interrupting threads.) |
|||
Line 117: | Line 117: | ||
To attach to a thread, the client sends a packet of the form: | To attach to a thread, the client sends a packet of the form: | ||
{ "to":<i>thread</i>, "type":"attach" } | { "to":<i>thread</i>, "type":"attach", "pause-for":<i>events</i> } | ||
The thread | This tells the thread to continue to run, but asks it to pause if any of | ||
the event described by <i>events</i> occurs. The form of <i>events</i> is | |||
described in [[#Events]]. | |||
The thread responds in one of two ways: | |||
{ "from":<i>thread</i>, "type":"attached" } | { "from":<i>thread</i>, "type":"attached" } | ||
This indicates that the thread received the <tt>attach</tt> packet, and will continue to run, reporting events of interest to the debugger. The thread is now in the | This indicates that the thread received the <tt>attach</tt> packet, and | ||
will continue to run, reporting events of interest to the debugger. The | |||
thread is now in the <b>Running</b> state. The actor name <i>thread</i> remains | |||
valid until the client detaches from the thread or acknowledges a thread | |||
exit. | |||
{ "from":<i>thread</i>, "type":"exited" } | { "from":<i>thread</i>, "type":"exited" } | ||
This indicates that the thread exited before receiving the <tt>attach</tt> packet. The thread is now in the | This indicates that the thread exited before receiving the <tt>attach</tt> | ||
packet. The thread is now in the <b>Exited</b> state. The client must | |||
respond to this with a packet of the form: | |||
{ "to":<i>thread</i>, "type":"release" } | { "to":<i>thread</i>, "type":"release" } | ||
At this point, the actor name <i>thread</i> is released and available for reuse, so the last trace of the thread's existence is gone. | At this point, the actor name <i>thread</i> is released and available for | ||
reuse, so the last trace of the thread's existence is gone. | |||
== Detaching From a Thread == | == Detaching From a Thread == | ||
Line 143: | Line 154: | ||
{ "from":<i>thread</i>, "type":"detached" } | { "from":<i>thread</i>, "type":"detached" } | ||
This indicates that the client has detached from the thread. The thread is now in the | This indicates that the client has detached from the thread. The thread is | ||
now in the <b>Detached</b> state: it can run freely, and no longer reports | |||
events to the client. The actor name <i>thread</i> is released and | |||
available for reuse. | |||
{ "from":<i>thread</i>, "type":"paused", ... } | { "from":<i>thread</i>, "type":"paused", ... } | ||
{ "from":<i>thread</i>, "type":"detached" } | { "from":<i>thread</i>, "type":"detached" } | ||
This series of packets indicates that the thread paused of its own accord (for | 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 <b>Detached</b> state, and the actor name is available | |||
for reuse. | |||
{ "from":<i>thread</i>, "type":"exited" } | { "from":<i>thread</i>, "type":"exited" } | ||
This indicates that the thread exited on its own before receiving the "detach" packet. The client should follow by sending a "release" packet, as described above. | This indicates that the thread exited on its own before receiving the | ||
"detach" packet. The client should follow by sending a "release" packet, as | |||
described above. | |||
== Running Threads == | == Running Threads == | ||
Once the client has attached to a thread, it is in the | Once the client has attached to a thread, it is in the <b>Running</b> | ||
state. In this state, four things can happen: | |||
* The thread can hit a breakpoint or watchpoint, or encounter some other condition of interest to the client. | * The thread can hit a breakpoint or watchpoint, or encounter some other condition of interest to the client. | ||
* The thread | * The thread can exit. | ||
* The client | * The client can detach from the thread. | ||
* The client can interrupt the running thread. | |||
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. | |||
== Thread Pauses == | |||
If the thread pauses to report an interesting event to the client, it sends | |||
a packet of the form: | |||
{ "from":<i>thread</i>, "type":"paused", "frame":<i>frame</i>, "reason":<i>reason</i> } | |||
This indicates that the thread is in the <b>Paused</b> state. The | |||
<i>frame</i> value describes the top frame on the JavaScript stack; see | |||
[[#Frames|frames]], below. The <i>reason</i> value describes why the thread | |||
paused. It has one of the following forms: | |||
{ "type":"breakpoint", "actor":<i>actor</i> } | |||
The thread stopped at the breakpoint represented by the actor named | |||
<i>actor</i>. | |||
{ "type":"watchpoint", "actor":<i>watchpoint</i> } | |||
The thread stopped at the breakpoint represented by the actor named | |||
<i>actor</i>. | |||
{ "type":"stepped" } | |||
The client had asked the thread to step to the next statement, and the | |||
thread completed that step. | |||
{ "type":"pre-call" } | |||
The client had asked the thread to pause before making each function call, | |||
and the thread is about to call a function. Single-stepping the thread will | |||
place it at the head of the function's code, with all arguments, local | |||
variables, and local functions bound. | |||
{ "type":"pre-return" } | |||
The client had asked the thread to pause before returning from functions, | |||
and the thread is about to return from a function. Single-stepping the | |||
thread will return the thread to the calling frame. | |||
{ "type":"pre-throw", "exception":<i>grip</i> } | |||
The client had asked the thread to pause before throwing an exception; | |||
<i>grip</i> is the name of an actor representing the exception value being | |||
thrown. Control is still at the point of the throw; it has not yet passed | |||
to a catch clause. Single-stepping this thread will report either a | |||
"caught" or "uncaught" pause. | |||
{ "type":"caught", "exception":<i>grip</i> } | |||
The client stepped the thread from a "pre-throw" pause, and a catch clause | |||
has been found for the exception referred to by <i>grip</i>; control is | |||
stopped at the head of the catch clause, with catch variable bindings made. | |||
If the catch is conditional, control is at the beginning of the condition. | |||
{ "type":uncaught", "exception":<i>grip</i> } | |||
The client stepped the thread from a "pre-throw" pause, and no catch clause | |||
was found for the exception. <i>(I'm not sure which code the thread is | |||
executing at this point; we might as well reveal SpiderMonkey's natural | |||
behavior.)</i> | |||
{ "type":"pre-throw-by-guard", "exception":<i>grip</i> } | |||
The thread had been stopped in a conditional guard, and the client asked | |||
the thread to continue but pause before throwing an exception. The guard | |||
condition evaluated to false, and the thread is about to re-throw the | |||
exception value, <i>grip</i>. | |||
== Resuming a Thread == | == Resuming a Thread == | ||
If a thread is in the <b>Paused</b> state, the client can resume it by | |||
sending a packet of the following form: | |||
{ "to":<i>thread</i>, "type":"attach", "pause-for":<i>events</i> } | |||
This puts the thread in the <b>Running</b> state, but asks it to pause if | |||
any of the event described by <i>events</i> occurs. The form of | |||
<i>events</i> is described in [[#Events]]. | |||
== Interrupting a Thread == | |||
If a thread is in the <b>Running</b> state, the client can cause it to | |||
pause where it is by sending a packet of the following form: | |||
{ "to":<i>thread</i>, "type":"interrupt" } | |||
The thread responds in one of three ways: | |||
{ "from":<i>thread</i>, "type":"interrupted" } | |||
This indicates that the thread stopped due to the client's | |||
<tt>interrupt</tt> packet, and is now in the <b>Paused</b> state. | |||
{ "from":<i>thread</i>, "type":"paused", "frame":<i>frame</i>, "reason":<i>reason</i> } | |||
This indicates that the thread stopped of its own accord before receiving | |||
the client's <tt>interrupt</tt> packet, and is now in the <b>Paused</b> | |||
state. The meanings of the thread's packet's properties are as for an | |||
ordinary pause. The thread will ignore the client's interrupt packet when | |||
it receives it. | |||
{ "from":<i>thread</i>, "type":"exited" } | |||
This indicates that the thread exited before receiving the client's | |||
<tt>interrupt</tt> packet, and is now in the <b>Exited</b> state. The | |||
client should send a <tt>release</tt> packet, as described above in | |||
[[#Detaching_From_a_Thread]]. | |||
= Events = | |||
= Grips = | |||
= Frames = |