Remote Debugging Protocol: Difference between revisions

Add sections on running, pausing, resuming, and interrupting threads.
(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 will respond in one of two ways:
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 "Running" state. The actor name <i>thread</i> remains valid until the client detaches from the thread or acknowledges a thread exit.
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 "Exited" state. The client must respond with a packet of the form:
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 "Detached" 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.
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 some reason given by the additional properties of the first packet), and only then received the "detach" packet. As above, this indicates that the thread is in the "Detached" state, and the actor name is available for reuse.
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 "Running" state. In this state, three things can happen:
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 could exit.
* The thread can exit.
* The client could interrupt the running thread.
* 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:


Naturally, the third is not exclusive of the first two. The protocol is designed to avoid ambiguities when both client and thread act simultaneously.
  { "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 =
Confirmed users
496

edits