xref: /aosp_15_r20/dalvik/docs/debugmon.html (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui<HTML>
2*055d4590SKeyi Gui
3*055d4590SKeyi Gui
4*055d4590SKeyi Gui<head>
5*055d4590SKeyi Gui  <title>Dalvik VM Debug Monitor</title>
6*055d4590SKeyi Gui  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7*055d4590SKeyi Gui  <link href="http://www.google.com/favicon.ico" type="image/x-icon"
8*055d4590SKeyi Gui rel="shortcut icon">
9*055d4590SKeyi Gui  <link href="../android.css" type="text/css" rel="stylesheet">
10*055d4590SKeyi Gui  <script language="JavaScript1.2" type="text/javascript">
11*055d4590SKeyi Guifunction highlight(name) {
12*055d4590SKeyi Gui  if (document.getElementById) {
13*055d4590SKeyi Gui    tags              = [ 'span', 'div', 'tr', 'td' ];
14*055d4590SKeyi Gui    for (i in tags) {
15*055d4590SKeyi Gui      elements        = document.getElementsByTagName(tags[i]);
16*055d4590SKeyi Gui      if (elements) {
17*055d4590SKeyi Gui        for (j = 0; j < elements.length; j++) {
18*055d4590SKeyi Gui          elementName = elements[j].getAttribute("id");
19*055d4590SKeyi Gui          if (elementName == name) {
20*055d4590SKeyi Gui            elements[j].style.backgroundColor = "#C0F0C0";
21*055d4590SKeyi Gui          } else if (elementName && elementName.indexOf("rev") == 0) {
22*055d4590SKeyi Gui            elements[j].style.backgroundColor = "#FFFFFF";
23*055d4590SKeyi Gui          }
24*055d4590SKeyi Gui        }
25*055d4590SKeyi Gui      }
26*055d4590SKeyi Gui    }
27*055d4590SKeyi Gui  }
28*055d4590SKeyi Gui}
29*055d4590SKeyi Gui  </script>
30*055d4590SKeyi Gui</head>
31*055d4590SKeyi Gui<body onload="prettyPrint()">
32*055d4590SKeyi Gui
33*055d4590SKeyi Gui<h1><a name="My_Project_"></a>Dalvik VM<br>Debug Monitor</h1>
34*055d4590SKeyi Gui
35*055d4590SKeyi Gui<!-- Status is one of: Draft, Current, Needs Update, Obsolete -->
36*055d4590SKeyi Gui<p style="text-align:center"><strong>Status:</strong><em>Draft</em> &nbsp;
37*055d4590SKeyi Gui<small>(as of March 6, 2007)</small></p>
38*055d4590SKeyi Gui<address>
39*055d4590SKeyi Gui[authors]
40*055d4590SKeyi Gui</address>
41*055d4590SKeyi Gui
42*055d4590SKeyi Gui<!-- last modified date can be different to the "Status date." It automatically
43*055d4590SKeyi Guiupdates
44*055d4590SKeyi Guiwhenever the file is modified. -->
45*055d4590SKeyi Gui<i>Modified:</i>
46*055d4590SKeyi Gui <!-- this script automatically sets the modified date,you don't need to modify
47*055d4590SKeyi Guiit -->
48*055d4590SKeyi Gui    <script type=text/javascript>
49*055d4590SKeyi Gui        <!--
50*055d4590SKeyi Gui        var lm = new Date(document.lastModified);
51*055d4590SKeyi Gui        document.write(lm.toDateString());
52*055d4590SKeyi Gui        //-->
53*055d4590SKeyi Gui        </script>
54*055d4590SKeyi Gui</address>
55*055d4590SKeyi Gui
56*055d4590SKeyi Gui<p><br>
57*055d4590SKeyi Gui<HR>
58*055d4590SKeyi Gui
59*055d4590SKeyi Gui<h2>Introduction</h2>
60*055d4590SKeyi Gui
61*055d4590SKeyi Gui<p>It's extremely useful to be able to monitor the live state of the
62*055d4590SKeyi GuiVM.  For Android, we need to monitor multiple VMs running on a device
63*055d4590SKeyi Guiconnected through USB or a wireless network connection.  This document
64*055d4590SKeyi Guidescribes a debug monitor server that interacts with multiple VMs, and
65*055d4590SKeyi Guian API that VMs and applications can use to provide information
66*055d4590SKeyi Guito the monitor.
67*055d4590SKeyi Gui
68*055d4590SKeyi Gui<p>Some things we can monitor with the Dalvik Debug Monitor ("DDM"):
69*055d4590SKeyi Gui<ul>
70*055d4590SKeyi Gui    <li> Thread states.  Track thread creation/exit, busy/idle status.
71*055d4590SKeyi Gui    <li> Overall heap status, useful for a heap bitmap display or
72*055d4590SKeyi Gui    fragmentation analysis.
73*055d4590SKeyi Gui</ul>
74*055d4590SKeyi Gui
75*055d4590SKeyi Gui<p>It is possible for something other than a VM to act as a DDM client, but
76*055d4590SKeyi Guithat is a secondary goal.  Examples include "logcat" log extraction
77*055d4590SKeyi Guiand system monitors for virtual memory usage and load average.
78*055d4590SKeyi Gui
79*055d4590SKeyi Gui<p>It's also possible for the DDM server to be run on the device, with
80*055d4590SKeyi Guithe information presented through the device UI.  However, the initial goal
81*055d4590SKeyi Guiis to provide a display tool that takes advantage of desktop tools and
82*055d4590SKeyi Guiscreen real estate.
83*055d4590SKeyi Gui
84*055d4590SKeyi Gui<p>This work is necessary because we are unable to use standard JVMTI-based
85*055d4590SKeyi Guitools with Dalvik.  JVMTI relies on bytecode insertion, which is not
86*055d4590SKeyi Guicurrently possible because Dalvik doesn't support Java bytecode.
87*055d4590SKeyi Gui
88*055d4590SKeyi Gui<p>The DDM server is written in the Java programming language
89*055d4590SKeyi Guifor portability.  It uses a desktop
90*055d4590SKeyi GuiUI toolkit (SWT) for its interface.
91*055d4590SKeyi Gui
92*055d4590SKeyi Gui
93*055d4590SKeyi Gui<h2>Protocol</h2>
94*055d4590SKeyi Gui
95*055d4590SKeyi Gui<p>To take advantage of existing infrastructure we are piggy-backing the
96*055d4590SKeyi GuiDDM protocol on top of JDWP (the Java Debug Wire Protocol, normally spoken
97*055d4590SKeyi Guibetween a VM and a debugger).  To a
98*055d4590SKeyi Guinon-DDM client, the DDM server just looks like a debugger.
99*055d4590SKeyi Gui
100*055d4590SKeyi Gui<p>The JDWP protocol is very close to what we want to use.  In particular:
101*055d4590SKeyi Gui<ul>
102*055d4590SKeyi Gui    <li>It explicitly allows for vendor-defined packets, so there is no
103*055d4590SKeyi Gui    need to "bend" the JDWP spec.
104*055d4590SKeyi Gui    <li>Events may be posted from the VM at arbitrary points.  Such
105*055d4590SKeyi Gui    events do not elicit a response from the debugger, meaning the client
106*055d4590SKeyi Gui    can post data and immediately resume work without worrying about the
107*055d4590SKeyi Gui    eventual response.
108*055d4590SKeyi Gui    <li>The basic protocol is stateless and asynchronous.  Request packets
109*055d4590SKeyi Gui    from the debugger side include a serial number, which the VM includes
110*055d4590SKeyi Gui    in the response packet.  This allows multiple simultaneous
111*055d4590SKeyi Gui    conversations, which means the DDM traffic can be interleaved with
112*055d4590SKeyi Gui    debugger traffic.
113*055d4590SKeyi Gui</ul>
114*055d4590SKeyi Gui
115*055d4590SKeyi Gui<p>There are a few issues with using JDWP for our purposes:
116*055d4590SKeyi Gui<ul>
117*055d4590SKeyi Gui    <li>The VM only expects one connection from a debugger, so you couldn't
118*055d4590SKeyi Gui    attach the monitor and a debugger at the same time.  This will be
119*055d4590SKeyi Gui    worked around by connecting the debugger to the monitor and passing the
120*055d4590SKeyi Gui    traffic through.  (We're already doing the pass-through with "jdwpspy";
121*055d4590SKeyi Gui    requires some management of our request IDs though.)  This should
122*055d4590SKeyi Gui    be more convenient than the current "guess the port
123*055d4590SKeyi Gui    number" system when we're attached to a device.
124*055d4590SKeyi Gui    <li>The VM behaves differently when a debugger is attached.  It will
125*055d4590SKeyi Gui    run more slowly, and any objects passed to the monitor or debugger are
126*055d4590SKeyi Gui    immune to GC.  We can work around this by not enabling the slow path
127*055d4590SKeyi Gui    until non-DDM traffic is observed.  We also want to have a "debugger
128*055d4590SKeyi Gui    has connected/disconnected" message that allows the VM to release
129*055d4590SKeyi Gui    debugger-related resources without dropping the net connection.
130*055d4590SKeyi Gui    <li>Non-DDM VMs should not freak out when DDM connects.  There are
131*055d4590SKeyi Gui    no guarantees here for 3rd-party VMs (e.g. a certain mainstream VM,
132*055d4590SKeyi Gui    which crashes instantly), but our older JamVM can be
133*055d4590SKeyi Gui    configured to reject the "hello" packet.
134*055d4590SKeyi Gui</ul>
135*055d4590SKeyi Gui
136*055d4590SKeyi Gui
137*055d4590SKeyi Gui<h3>Connection Establishment</h3>
138*055d4590SKeyi Gui
139*055d4590SKeyi Gui<p>There are two basic approaches: have the server contact the VMs, and
140*055d4590SKeyi Guihave the VMs contact the server.  The former is less "precise" than the
141*055d4590SKeyi Guilatter, because you have to scan for the clients, but it has some
142*055d4590SKeyi Guiadvantages.
143*055d4590SKeyi Gui
144*055d4590SKeyi Gui<p>There are three interesting scenarios:
145*055d4590SKeyi Gui<ol>
146*055d4590SKeyi Gui    <li>The DDM server is started, then the USB-attached device is booted
147*055d4590SKeyi Gui    or the simulator is launched.
148*055d4590SKeyi Gui    <li>The device or simulator is already running when the DDM server
149*055d4590SKeyi Gui    is started.
150*055d4590SKeyi Gui    <li>The DDM server is running when an already-started device is
151*055d4590SKeyi Gui    attached to USB.
152*055d4590SKeyi Gui</ol>
153*055d4590SKeyi Gui<p>If we have the VMs connect to the DDM server on startup, we only handle
154*055d4590SKeyi Guicase #1.  If the DDM server scans for VMs when it starts, we only handle
155*055d4590SKeyi Guicase #2.  Neither handles case #3, which is probably the most important
156*055d4590SKeyi Guiof the bunch as the device matures.
157*055d4590SKeyi Gui<p>The plan is to have a drop-down menu with two entries,
158*055d4590SKeyi Gui"scan workstation" and "scan device".
159*055d4590SKeyi GuiThe former causes the DDM server to search for VMs on "localhost", the
160*055d4590SKeyi Guilatter causes it to search for VMs on the other side of an ADB connection.
161*055d4590SKeyi GuiThe DDM server will scan for VMs every few seconds, either checking a
162*055d4590SKeyi Guirange of known VM ports (e.g. 8000-8040) or interacting with some sort
163*055d4590SKeyi Guiof process database on the device.  Changing modes causes all existing
164*055d4590SKeyi Guiconnections to be dropped.
165*055d4590SKeyi Gui<p>When the DDM server first starts, it will try to execute "adb usb"
166*055d4590SKeyi Guito ensure that the ADB server is running.  (Note it will be necessary
167*055d4590SKeyi Guito launch the DDM server from a shell with "adb" in the path.)  If this
168*055d4590SKeyi Guifails, talking to the device will still be possible so long as the ADB
169*055d4590SKeyi Guidaemon is already running.
170*055d4590SKeyi Gui
171*055d4590SKeyi Gui<h4>Connecting a Debugger</h4>
172*055d4590SKeyi Gui
173*055d4590SKeyi Gui<p>With the DDM server sitting on the JDWP port of all VMs, it will be
174*055d4590SKeyi Guinecessary to connect the debugger through the DDM server.  Each VM being
175*055d4590SKeyi Guidebugged will have a separate port being listened to by the DDM server,
176*055d4590SKeyi Guiallowing you to connect a debugger to one or more VMs simultaneously.
177*055d4590SKeyi Gui
178*055d4590SKeyi Gui<p>In the common case, however, the developer will only want to debug
179*055d4590SKeyi Guia single VM.  One port (say 8700) will be listened to by the DDM server,
180*055d4590SKeyi Guiand anything connecting to it will be connected to the "current VM"
181*055d4590SKeyi Gui(selected in the UI).  This should allow developers to focus on a
182*055d4590SKeyi Guisingle application, which may otherwise shift around in the ordering, without
183*055d4590SKeyi Guihaving to adjust their IDE settings to a different port every time they
184*055d4590SKeyi Guirestart the device.
185*055d4590SKeyi Gui
186*055d4590SKeyi Gui
187*055d4590SKeyi Gui<h3>Packet Format</h3>
188*055d4590SKeyi Gui
189*055d4590SKeyi Gui<p>Information is sent in chunks.  Each chunk starts with:
190*055d4590SKeyi Gui<pre>
191*055d4590SKeyi Guiu4   type
192*055d4590SKeyi Guiu4   length
193*055d4590SKeyi Gui</pre>
194*055d4590SKeyi Guiand contains a variable amount of type-specific data.
195*055d4590SKeyi GuiUnrecognized types cause an empty response from the client and
196*055d4590SKeyi Guiare quietly ignored by the server.  [Should probably return an error;
197*055d4590SKeyi Guineed an "error" chunk type and a handler on the server side.]
198*055d4590SKeyi Gui
199*055d4590SKeyi Gui<p>The same chunk type may have different meanings when sent in different
200*055d4590SKeyi Guidirections.  For example, the same type may be used for both a query and
201*055d4590SKeyi Guia response to the query.  The same type must always be used in
202*055d4590SKeyi Guirelated transactions.
203*055d4590SKeyi Gui
204*055d4590SKeyi Gui<p>This is somewhat redundant with the JDWP framing, which includes a
205*055d4590SKeyi Gui4-byte length and a two-byte type code ("command set" and "command"; a
206*055d4590SKeyi Guirange of command set values is designated for "vendor-defined commands
207*055d4590SKeyi Guiand extensions").  Using the chunk format allows us to remain independent
208*055d4590SKeyi Guiof the underlying transport, avoids intrusive integration
209*055d4590SKeyi Guiwith JDWP client code, and provides a way to send multiple chunks in a
210*055d4590SKeyi Guisingle transmission unit.  [I'm taking the multi-chunk packets into
211*055d4590SKeyi Guiaccount in the design, but do not plan to implement them unless the need
212*055d4590SKeyi Guiarises.]
213*055d4590SKeyi Gui
214*055d4590SKeyi Gui<p>Because we may be sending data over a slow USB link, the chunks may be
215*055d4590SKeyi Guicompressed.  Compressed chunks are written as a chunk type that
216*055d4590SKeyi Guiindicates the compression, followed by the compressed length, followed
217*055d4590SKeyi Guiby the original chunk type and the uncompressed length.  For zlib's deflate
218*055d4590SKeyi Guialgorithm, the chunk type is "ZLIB".
219*055d4590SKeyi Gui
220*055d4590SKeyi Gui<p>Following the JDWP model, packets sent from the server to the client
221*055d4590SKeyi Guiare always acknowledged, but packets sent from client to server never are.
222*055d4590SKeyi GuiThe JDWP error code field is always set to "no error"; failure responses
223*055d4590SKeyi Guifrom specific requests must be encoded into the DDM messages.
224*055d4590SKeyi Gui
225*055d4590SKeyi Gui<p>In what follows "u4" is an unsigned 32-bit value and "u1" is an
226*055d4590SKeyi Guiunsigned 8-bit value.  Values are written in big-endian order to match
227*055d4590SKeyi GuiJDWP.
228*055d4590SKeyi Gui
229*055d4590SKeyi Gui
230*055d4590SKeyi Gui<h3>Initial Handshake</h3>
231*055d4590SKeyi Gui
232*055d4590SKeyi Gui<p>After the JDWP handshake, the server sends a HELO chunk to the client.
233*055d4590SKeyi GuiIf the client's JDWP layer rejects it, the server assumes that the client
234*055d4590SKeyi Guiis not a DDM-aware VM, and does not send it any further DDM queries.
235*055d4590SKeyi Gui<p>On the client side, upon seeing a HELO it can know that a DDM server
236*055d4590SKeyi Guiis attached and prepare accordingly.  The VM should not assume that a
237*055d4590SKeyi Guidebugger is attached until a non-DDM packet arrives.
238*055d4590SKeyi Gui
239*055d4590SKeyi Gui<h4>Chunk HELO (server --&gt; client)</h4>
240*055d4590SKeyi Gui<p>Basic "hello" message.
241*055d4590SKeyi Gui<pre>
242*055d4590SKeyi Guiu4   DDM server protocol version
243*055d4590SKeyi Gui</pre>
244*055d4590SKeyi Gui
245*055d4590SKeyi Gui
246*055d4590SKeyi Gui<h4>Chunk HELO (client --&gt; server, reply only)</h4>
247*055d4590SKeyi GuiInformation about the client.  Must be sent in response to the HELO message.
248*055d4590SKeyi Gui<pre>
249*055d4590SKeyi Guiu4   DDM client protocol version
250*055d4590SKeyi Guiu4   pid
251*055d4590SKeyi Guiu4   VM ident string len (in 16-bit units)
252*055d4590SKeyi Guiu4   application name len (in 16-bit units)
253*055d4590SKeyi Guivar  VM ident string (UTF-16)
254*055d4590SKeyi Guivar  application name (UTF-16)
255*055d4590SKeyi Gui</pre>
256*055d4590SKeyi Gui
257*055d4590SKeyi Gui<p>If the client does not wish to speak to the DDM server, it should respond
258*055d4590SKeyi Guiwith a JDWP error packet.  This is the same behavior you'd get from a VM
259*055d4590SKeyi Guithat doesn't support DDM.
260*055d4590SKeyi Gui
261*055d4590SKeyi Gui
262*055d4590SKeyi Gui<h3>Debugger Management</h3>
263*055d4590SKeyi Gui<p>VMs usually prepare for debugging when a JDWP connection is established,
264*055d4590SKeyi Guiand release debugger-related resources when the connection drops.  We want
265*055d4590SKeyi Guito open the JDWP connection early and hold it open after the debugger
266*055d4590SKeyi Guidisconnects.
267*055d4590SKeyi Gui<p>The VM can tell when a debugger attaches, because it will start seeing
268*055d4590SKeyi Guinon-DDM JDWP traffic, but it can't identify the disconnect.  For this reason,
269*055d4590SKeyi Guiwe need to send a packet to the client when the debugger disconnects.
270*055d4590SKeyi Gui<p>If the DDM server is talking to a non-DDM-aware client, it will be
271*055d4590SKeyi Guinecessary to drop and re-establish the connection when the debugger goes away.
272*055d4590SKeyi Gui(This also works with DDM-aware clients; this packet is an optimization.)
273*055d4590SKeyi Gui
274*055d4590SKeyi Gui<h4>Chunk DBGD (server --&gt; client)</h4>
275*055d4590SKeyi Gui<p>Debugger has disconnected.  The client responds with a DBGD to acknowledge
276*055d4590SKeyi Guireceipt.  No data in request, no response required.
277*055d4590SKeyi Gui
278*055d4590SKeyi Gui
279*055d4590SKeyi Gui<h3>VM Info</h3>
280*055d4590SKeyi Gui<p>Update the server's info about the client.
281*055d4590SKeyi Gui
282*055d4590SKeyi Gui<h4>Chunk APNM (client --&gt; server)</h4>
283*055d4590SKeyi Gui
284*055d4590SKeyi Gui<p>If a VM's application name changes -- possible in our environment because
285*055d4590SKeyi Guiof the "pre-initialized" app processes -- it must send up one of these.
286*055d4590SKeyi Gui<pre>
287*055d4590SKeyi Guiu4   application name len (in 16-bit chars)
288*055d4590SKeyi Guivar  application name (UTF-16)
289*055d4590SKeyi Gui</pre>
290*055d4590SKeyi Gui
291*055d4590SKeyi Gui<h4>Chunk WAIT (client --&gt; server)</h4>
292*055d4590SKeyi Gui
293*055d4590SKeyi Gui<p>This tells DDMS that one or more threads are waiting on an external
294*055d4590SKeyi Guievent.  The simplest use is to tell DDMS that the VM is waiting for a
295*055d4590SKeyi Guidebugger to attach.
296*055d4590SKeyi Gui<pre>
297*055d4590SKeyi Guiu1   reason  (0 = wait for debugger)
298*055d4590SKeyi Gui</pre>
299*055d4590SKeyi GuiIf DDMS is attached, the client VM sends this up when waitForDebugger()
300*055d4590SKeyi Guiis called.  If waitForDebugger() is called before DDMS attaches, the WAIT
301*055d4590SKeyi Guichunk will be sent up at about the same time as the HELO response.
302*055d4590SKeyi Gui
303*055d4590SKeyi Gui
304*055d4590SKeyi Gui<h3>Thread Status</h3>
305*055d4590SKeyi Gui
306*055d4590SKeyi Gui<p>The client can send updates when their status changes, or periodically
307*055d4590SKeyi Guisend thread state info, e.g. 2x per
308*055d4590SKeyi Guisecond to allow a "blinkenlights" display of thread activity.
309*055d4590SKeyi Gui
310*055d4590SKeyi Gui<h4>Chunk THEN (server --&gt; client)</h4>
311*055d4590SKeyi Gui
312*055d4590SKeyi Gui<p>Enable thread creation/death notification.
313*055d4590SKeyi Gui<pre>
314*055d4590SKeyi Guiu1   boolean (true=enable, false=disable)
315*055d4590SKeyi Gui</pre>
316*055d4590SKeyi Gui<p>The response is empty.  The client generates THCR packets for all
317*055d4590SKeyi Guiknown threads.  (Note the THCR packets may arrive before the THEN
318*055d4590SKeyi Guiresponse.)
319*055d4590SKeyi Gui
320*055d4590SKeyi Gui<h4>Chunk THCR (client --&gt; server)</h4>
321*055d4590SKeyi Gui<p>Thread Creation notification.
322*055d4590SKeyi Gui<pre>
323*055d4590SKeyi Guiu4   VM-local thread ID (usually a small int)
324*055d4590SKeyi Guiu4   thread name len (in 16-bit chars)
325*055d4590SKeyi Guivar  thread name (UTF-16)
326*055d4590SKeyi Gui</pre>
327*055d4590SKeyi Gui
328*055d4590SKeyi Gui<h4>Chunk THDE (client --&gt; server)</h4>
329*055d4590SKeyi Gui<p>Thread Death notification.
330*055d4590SKeyi Gui<pre>
331*055d4590SKeyi Guiu4   VM-local thread ID
332*055d4590SKeyi Gui</pre>
333*055d4590SKeyi Gui
334*055d4590SKeyi Gui<h4>Chunk THST (server --&gt; client)</h4>
335*055d4590SKeyi Gui
336*055d4590SKeyi Gui<p>Enable periodic thread activity updates.
337*055d4590SKeyi GuiThreads in THCR messages are assumed to be in the "initializing" state.  A
338*055d4590SKeyi GuiTHST message should follow closely on the heels of THCR.
339*055d4590SKeyi Gui<pre>
340*055d4590SKeyi Guiu4   interval, in msec
341*055d4590SKeyi Gui</pre>
342*055d4590SKeyi Gui<p>An interval of 0 disables the updates.  This is done periodically,
343*055d4590SKeyi Guirather than every time the thread state changes, to reduce the amount
344*055d4590SKeyi Guiof data that must be sent for an actively running VM.
345*055d4590SKeyi Gui
346*055d4590SKeyi Gui<h4>Chunk THST (client --&gt; server)</h4>
347*055d4590SKeyi Gui<p>Thread Status, describing the state of one or more threads.  This is
348*055d4590SKeyi Guimost useful when creation/death notifications are enabled first.  The
349*055d4590SKeyi Guioverall layout is:
350*055d4590SKeyi Gui<pre>
351*055d4590SKeyi Guiu4   count
352*055d4590SKeyi Guivar  thread data
353*055d4590SKeyi Gui</pre>
354*055d4590SKeyi GuiThen, for every thread:
355*055d4590SKeyi Gui<pre>
356*055d4590SKeyi Guiu4   VM-local thread ID
357*055d4590SKeyi Guiu1   thread state
358*055d4590SKeyi Guiu1   suspended
359*055d4590SKeyi Gui</pre>
360*055d4590SKeyi Gui<p>"thread state" must be one of:
361*055d4590SKeyi Gui<ul>    <!-- don't use ol, we may need (-1) or sparse -->
362*055d4590SKeyi Gui    <li> 1 - running (now executing or ready to do so)
363*055d4590SKeyi Gui    <li> 2 - sleeping (in Thread.sleep())
364*055d4590SKeyi Gui    <li> 3 - monitor (blocked on a monitor lock)
365*055d4590SKeyi Gui    <li> 4 - waiting (in Object.wait())
366*055d4590SKeyi Gui    <li> 5 - initializing
367*055d4590SKeyi Gui    <li> 6 - starting
368*055d4590SKeyi Gui    <li> 7 - native (executing native code)
369*055d4590SKeyi Gui    <li> 8 - vmwait (waiting on a VM resource)
370*055d4590SKeyi Gui</ul>
371*055d4590SKeyi Gui<p>"suspended" will be 0 if the thread is running, 1 if not.
372*055d4590SKeyi Gui<p>[Any reason not to make "suspended" be the high bit of "thread state"?
373*055d4590SKeyi GuiDo we need to differentiate suspend-by-GC from suspend-by-debugger?]
374*055d4590SKeyi Gui<p>[We might be able to send the currently-executing method.  This is a
375*055d4590SKeyi Guilittle risky in a running VM, and increases the size of the messages
376*055d4590SKeyi Guiconsiderably, but might be handy.]
377*055d4590SKeyi Gui
378*055d4590SKeyi Gui
379*055d4590SKeyi Gui<h3>Heap Status</h3>
380*055d4590SKeyi Gui
381*055d4590SKeyi Gui<p>The client sends what amounts to a color-coded bitmap to the server,
382*055d4590SKeyi Guiindicating which stretches of memory are free and which are in use.  For
383*055d4590SKeyi Guicompactness the bitmap is run-length encoded, and based on multi-byte
384*055d4590SKeyi Gui"allocation units" rather than byte counts.
385*055d4590SKeyi Gui
386*055d4590SKeyi Gui<p>In the future the server will be able to correlate the bitmap with more
387*055d4590SKeyi Guidetailed object data, so enough information is provided to associate the
388*055d4590SKeyi Guibitmap data with virtual addresses.
389*055d4590SKeyi Gui
390*055d4590SKeyi Gui<p>Heaps may be broken into segments within the VM, and due to memory
391*055d4590SKeyi Guiconstraints it may be desirable to send the bitmap in smaller pieces,
392*055d4590SKeyi Guiso the protocol allows the heap data to be sent in several chunks.
393*055d4590SKeyi GuiTo avoid ambiguity, the client is required
394*055d4590SKeyi Guito send explicit "start" and "end" messages during an update.
395*055d4590SKeyi Gui
396*055d4590SKeyi Gui<p>All messages include a "heap ID" that can be used to differentiate
397*055d4590SKeyi Guibetween multiple independent virtual heaps or perhaps a native heap.  The
398*055d4590SKeyi Guiclient is allowed to send information about different heaps simultaneously,
399*055d4590SKeyi Guiso all heap-specific information is tagged with a "heap ID".
400*055d4590SKeyi Gui
401*055d4590SKeyi Gui<h4>Chunk HPIF (server --&gt; client)</h4>
402*055d4590SKeyi Gui<p>Request heap info.
403*055d4590SKeyi Gui<pre>
404*055d4590SKeyi Guiu1   when to send
405*055d4590SKeyi Gui</pre>
406*055d4590SKeyi Gui<p>The "when" values are:
407*055d4590SKeyi Gui<pre>
408*055d4590SKeyi Gui0: never
409*055d4590SKeyi Gui1: immediately
410*055d4590SKeyi Gui2: at the next GC
411*055d4590SKeyi Gui3: at every GC
412*055d4590SKeyi Gui</pre>
413*055d4590SKeyi Gui
414*055d4590SKeyi Gui<h4>Chunk HPIF (client --&gt; server, reply only)</h4>
415*055d4590SKeyi Gui<p>Heap Info.  General information about the heap, suitable for a summary
416*055d4590SKeyi Guidisplay.
417*055d4590SKeyi Gui<pre>
418*055d4590SKeyi Guiu4   number of heaps
419*055d4590SKeyi Gui</pre>
420*055d4590SKeyi GuiFor each heap:
421*055d4590SKeyi Gui<pre>
422*055d4590SKeyi Guiu4   heap ID
423*055d4590SKeyi Guiu8   timestamp in ms since Unix epoch
424*055d4590SKeyi Guiu1   capture reason (same as 'when' value from server)
425*055d4590SKeyi Guiu4   max heap size in bytes (-Xmx)
426*055d4590SKeyi Guiu4   current heap size in bytes
427*055d4590SKeyi Guiu4   current number of bytes allocated
428*055d4590SKeyi Guiu4   current number of objects allocated
429*055d4590SKeyi Gui</pre>
430*055d4590SKeyi Gui<p>[We can get some of this from HPSG, more from HPSO.]
431*055d4590SKeyi Gui<p>[Do we need a "heap overhead" stat here, indicating how much goes to
432*055d4590SKeyi Guiwaste?  e.g. (8 bytes per object * number of objects)]
433*055d4590SKeyi Gui
434*055d4590SKeyi Gui<h4>Chunk HPSG (server --&gt; client)</h4>
435*055d4590SKeyi Gui<p>Request transmission of heap segment data.
436*055d4590SKeyi Gui<pre>
437*055d4590SKeyi Guiu1   when to send
438*055d4590SKeyi Guiu1   what to send
439*055d4590SKeyi Gui</pre>
440*055d4590SKeyi Gui<p>The "when" to send will be zero to disable transmission, 1 to send
441*055d4590SKeyi Guiduring a GC.  Other values are currently undefined.  (Could use to pick
442*055d4590SKeyi Guiwhich part of the GC to send it, or cause periodic transmissions.)
443*055d4590SKeyi Gui<p>The "what" field is currently 0 for HPSG and 1 for HPSO.
444*055d4590SKeyi Gui<p>No reply is expected.
445*055d4590SKeyi Gui
446*055d4590SKeyi Gui<h4>Chunk NHSG (server --&gt; client)</h4>
447*055d4590SKeyi Gui<p>Request transmission of native heap segment data.
448*055d4590SKeyi Gui<pre>
449*055d4590SKeyi Guiu1   when to send
450*055d4590SKeyi Guiu1   what to send
451*055d4590SKeyi Gui</pre>
452*055d4590SKeyi Gui<p>The "when" to send will be zero to disable transmission, 1 to send
453*055d4590SKeyi Guiduring a GC.  Other values are currently undefined.
454*055d4590SKeyi Gui<p>The "what" field is currently ignored.
455*055d4590SKeyi Gui<p>No reply is expected.
456*055d4590SKeyi Gui
457*055d4590SKeyi Gui<h4>Chunk HPST/NHST (client --&gt; server)</h4>
458*055d4590SKeyi Gui<p>This is a Heap Start message.  It tells the server to discard any
459*055d4590SKeyi Guiexisting notion of what the client's heap looks like, and prepare for
460*055d4590SKeyi Guinew information.  HPST indicates a virtual heap dump and must be followed
461*055d4590SKeyi Guiby zero or more HPSG/HPSO messages and an HPEN.  NHST indicates a native
462*055d4590SKeyi Guiheap dump and must be followed by zero or more NHSG messages and an NHEN.
463*055d4590SKeyi Gui
464*055d4590SKeyi Gui<p>The only data item is:
465*055d4590SKeyi Gui<pre>
466*055d4590SKeyi Guiu4   heap ID
467*055d4590SKeyi Gui</pre>
468*055d4590SKeyi Gui
469*055d4590SKeyi Gui<h4>Chunk HPEN/NHEN (client --&gt; server)</h4>
470*055d4590SKeyi Gui<p>Heap End, indicating that all information about the heap has been sent.
471*055d4590SKeyi GuiA HPST will be paired with an HPEN and an NHST will be paired with an NHEN.
472*055d4590SKeyi Gui
473*055d4590SKeyi Gui<p>The only data item is:
474*055d4590SKeyi Gui<pre>
475*055d4590SKeyi Guiu4   heap ID
476*055d4590SKeyi Gui</pre>
477*055d4590SKeyi Gui
478*055d4590SKeyi Gui<h4>Chunk HPSG (client --&gt; server)</h4>
479*055d4590SKeyi Gui<p>Heap segment data.  Each chunk describes all or part of a contiguous
480*055d4590SKeyi Guistretch of heap memory.
481*055d4590SKeyi Gui<pre>
482*055d4590SKeyi Guiu4   heap ID
483*055d4590SKeyi Guiu1   size of allocation unit, in bytes (e.g. 8 bytes)
484*055d4590SKeyi Guiu4   virtual address of segment start
485*055d4590SKeyi Guiu4   offset of this piece (relative to the virtual address)
486*055d4590SKeyi Guiu4   length of piece, in allocation units
487*055d4590SKeyi Guivar  usage data
488*055d4590SKeyi Gui</pre>
489*055d4590SKeyi Gui<p>The "usage data" indicates the status of each allocation unit.  The data
490*055d4590SKeyi Guiis a stream of pairs of bytes, where the first byte indicates the state
491*055d4590SKeyi Guiof the allocation unit, and the second byte indicates the number of
492*055d4590SKeyi Guiconsecutive allocation units with the same state.
493*055d4590SKeyi Gui<p>The bits in the "state" byte have the following meaning:
494*055d4590SKeyi Gui<pre>
495*055d4590SKeyi Gui+---------------------------------------+
496*055d4590SKeyi Gui|  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
497*055d4590SKeyi Gui+---------------------------------------+
498*055d4590SKeyi Gui|  P | U0 | K2 | K1 | K0 | S2 | S1 | S0 |
499*055d4590SKeyi Gui+---------------------------------------+
500*055d4590SKeyi Gui</pre>
501*055d4590SKeyi Gui<ul>
502*055d4590SKeyi Gui    <li>'S': solidity
503*055d4590SKeyi Gui    <ul>
504*055d4590SKeyi Gui        <li>0=free
505*055d4590SKeyi Gui        <li>1=has hard reference
506*055d4590SKeyi Gui        <li>2=has soft reference
507*055d4590SKeyi Gui        <li>3=has weak reference
508*055d4590SKeyi Gui        <li>4=has phantom reference
509*055d4590SKeyi Gui        <li>5=pending finalization
510*055d4590SKeyi Gui        <li>6=marked, about to be swept
511*055d4590SKeyi Gui    </ul>
512*055d4590SKeyi Gui    <li>'K': kind
513*055d4590SKeyi Gui    <ul>
514*055d4590SKeyi Gui        <li>0=object
515*055d4590SKeyi Gui        <li>1=class object
516*055d4590SKeyi Gui        <li>2=array of byte/boolean
517*055d4590SKeyi Gui        <li>3=array of char/short
518*055d4590SKeyi Gui        <li>4=array of Object/int/float
519*055d4590SKeyi Gui        <li>5=array of long/double
520*055d4590SKeyi Gui    </ul>
521*055d4590SKeyi Gui    <li>'P': partial flag (not used for HPSG)
522*055d4590SKeyi Gui    <li>'U': unused, must be zero
523*055d4590SKeyi Gui</ul>
524*055d4590SKeyi Gui
525*055d4590SKeyi Gui<p>The use of the various 'S' types depends on when the information is
526*055d4590SKeyi Guisent.  The current plan is to send it either immediately after a GC,
527*055d4590SKeyi Guior between the "mark" and "sweep" phases of the GC.  For a fancy generational
528*055d4590SKeyi Guicollector, we may just want to send it up periodically.
529*055d4590SKeyi Gui
530*055d4590SKeyi Gui<p>The run-length byte indicates the number of allocation units minus one, so a
531*055d4590SKeyi Guilength of 255 means there are 256 consecutive units with this state.  In
532*055d4590SKeyi Guisome cases, e.g. arrays of bytes, the actual size of the data is rounded
533*055d4590SKeyi Guiup the nearest allocation unit.
534*055d4590SKeyi Gui<p>For HPSG, the runs do not end at object boundaries.  It is not possible
535*055d4590SKeyi Guito tell from this bitmap whether a run contains one or several objects.
536*055d4590SKeyi Gui(But see HPSO, below.)
537*055d4590SKeyi Gui<p>[If we find that we have many long runs, we can overload the 'P' flag
538*055d4590SKeyi Guior dedicate the 'U' flag to indicate that we have a 16-bit length instead
539*055d4590SKeyi Guiof 8-bit.  We can also use a variable-width integer scheme for the length,
540*055d4590SKeyi Guiencoding 1-128 in one byte, 1-16384 in two bytes, etc.]
541*055d4590SKeyi Gui<p>[Alternate plan for 'K': array of byte, array of char, array of Object,
542*055d4590SKeyi Guiarray of miscellaneous primitive type]
543*055d4590SKeyi Gui<p>To parse the data, the server runs through the usage data until either
544*055d4590SKeyi Gui(a) the end of the chunk is reached, or (b) all allocation units have been
545*055d4590SKeyi Guiaccounted for.  (If these two things don't happen at the same time, the
546*055d4590SKeyi Guichunk is rejected.)
547*055d4590SKeyi Gui<p>Example: suppose a VM has a heap at 0x10000 that is 0x2000 bytes long
548*055d4590SKeyi Gui(with an 8-byte allocation unit size, that's 0x0400 units long).
549*055d4590SKeyi GuiThe client could send one chunk (allocSize=8, virtAddr=0x10000, offset=0,
550*055d4590SKeyi Guilength=0x0400) or two (allocSize=8, virtAddr=0x10000, offset=0, length=0x300;
551*055d4590SKeyi Guithen allocSize=8, virtAddr=0x10000, offset=0x300, length=0x100).
552*055d4590SKeyi Gui<p>The client must encode the entire heap, including all free space at
553*055d4590SKeyi Guithe end, or the server will not have an accurate impression of the amount
554*055d4590SKeyi Guiof memory in the heap.  This refers to the current heap size, not the
555*055d4590SKeyi Guimaximum heap size.
556*055d4590SKeyi Gui
557*055d4590SKeyi Gui<h4>Chunk HPSO (client --&gt; server)</h4>
558*055d4590SKeyi Gui<p>This is essentially identical to HPSG, but the runs are terminated at
559*055d4590SKeyi Guiobject boundaries.  If an object is larger than 256 allocation units, the
560*055d4590SKeyi Gui"partial" flag is set in all runs except the last.
561*055d4590SKeyi Gui<p>The resulting unpacked bitmap is identical, but the object boundary
562*055d4590SKeyi Guiinformation can be used to gain insights into heap layout.
563*055d4590SKeyi Gui<p>[Do we want to have a separate message for this?  Maybe just include
564*055d4590SKeyi Guia "variant" flag in the HPST packet.  Another possible form of output
565*055d4590SKeyi Guiwould be one that indicates the age, in generations, of each block of
566*055d4590SKeyi Guimemory.  That would provide a quick visual indication of "permanent vs.
567*055d4590SKeyi Guitransient residents", perhaps with a 16-level grey scale.]
568*055d4590SKeyi Gui
569*055d4590SKeyi Gui<h4>Chunk NHSG (client --&gt; server)</h4>
570*055d4590SKeyi Gui<p>Native heap segment data.  Each chunk describes all or part of a
571*055d4590SKeyi Guicontiguous stretch of native heap memory.  The format is the same as
572*055d4590SKeyi Guifor HPSG, except that only solidity values 0 (= free) and 1 (= hard
573*055d4590SKeyi Guireference) are used, and the kind value is always 0 for free chunks
574*055d4590SKeyi Guiand 7 for allocated chunks, indicating a non-VM object.
575*055d4590SKeyi Gui<pre>
576*055d4590SKeyi Guiu4   heap ID
577*055d4590SKeyi Guiu1   size of allocation unit, in bytes (e.g. 8 bytes)
578*055d4590SKeyi Guiu4   virtual address of segment start
579*055d4590SKeyi Guiu4   offset of this piece (relative to the virtual address)
580*055d4590SKeyi Guiu4   length of piece, in allocation units
581*055d4590SKeyi Guivar  usage data
582*055d4590SKeyi Gui</pre>
583*055d4590SKeyi Gui
584*055d4590SKeyi Gui<h3>Generic Replies</h3>
585*055d4590SKeyi Gui
586*055d4590SKeyi GuiThe client-side chunk handlers need a common way to report simple success
587*055d4590SKeyi Guior failure.  By convention, an empty reply packet indicates success.
588*055d4590SKeyi Gui
589*055d4590SKeyi Gui<h4>Chunk FAIL (client --&gt; server, reply only)</h4>
590*055d4590SKeyi Gui<p>The chunk includes a machine-readable error code and a
591*055d4590SKeyi Guihuman-readable error message.  Server code can associate the failure
592*055d4590SKeyi Guiwith the original request by comparing the JDWP packet ID.
593*055d4590SKeyi Gui<p>This allows a standard way of, for example, rejecting badly-formed
594*055d4590SKeyi Guirequest packets.
595*055d4590SKeyi Gui<pre>
596*055d4590SKeyi Guiu4   error code
597*055d4590SKeyi Guiu4   error message len (in 16-bit chars)
598*055d4590SKeyi Guivar  error message (UTF-16)
599*055d4590SKeyi Gui</pre>
600*055d4590SKeyi Gui
601*055d4590SKeyi Gui<h3>Miscellaneous</h3>
602*055d4590SKeyi Gui
603*055d4590SKeyi Gui<h4>Chunk EXIT (server --&gt; client)</h4>
604*055d4590SKeyi Gui<p>Cause the client to exit with the specified status, using System.exit().
605*055d4590SKeyi GuiUseful for certain kinds of testing.
606*055d4590SKeyi Gui<pre>
607*055d4590SKeyi Guiu4   exit status
608*055d4590SKeyi Gui</pre>
609*055d4590SKeyi Gui
610*055d4590SKeyi Gui<h4>Chunk DTRC (server --&gt; client)</h4>
611*055d4590SKeyi Gui<p>[TBD] start/stop dmtrace; can send the results back over the wire.  For
612*055d4590SKeyi Guisize reasons we probably need "sending", "data", "key", "finished" as
613*055d4590SKeyi Gui4 separate chunks/packets rather than one glob.
614*055d4590SKeyi Gui
615*055d4590SKeyi Gui
616*055d4590SKeyi Gui<h2>Client API</h2>
617*055d4590SKeyi Gui
618*055d4590SKeyi Gui<p>The API is written in the Java programming language
619*055d4590SKeyi Guifor convenience.  The code is free to call native methods if appropriate.
620*055d4590SKeyi Gui
621*055d4590SKeyi Gui<h3>Chunk Handler API</h3>
622*055d4590SKeyi Gui
623*055d4590SKeyi Gui<p>The basic idea is that arbitrary code can register handlers for
624*055d4590SKeyi Guispecific chunk types.  When a DDM chunk with that type arrives, the
625*055d4590SKeyi Guiappropriate handler is invoked.  The handler's return value provides the
626*055d4590SKeyi Guiresponse to the server.
627*055d4590SKeyi Gui
628*055d4590SKeyi Gui<p>There are two packages.  android.ddm lives in the "framework" library,
629*055d4590SKeyi Guiand has all of the chunk handlers and registration code.  It can freely
630*055d4590SKeyi Guiuse Android classes.  org.apache.harmony.dalvik.ddmc lives in the "core"
631*055d4590SKeyi Guilibrary, and has
632*055d4590SKeyi Guisome base classes and features that interact with the VM.  Nothing should
633*055d4590SKeyi Guineed to modify the org.apache.harmony.dalvik.ddmc classes.
634*055d4590SKeyi Gui
635*055d4590SKeyi Gui<p>The DDM classes pass chunks of data around with a simple class:
636*055d4590SKeyi Gui
637*055d4590SKeyi Gui<pre class=prettyprint>
638*055d4590SKeyi Guiclass Chunk {
639*055d4590SKeyi Gui    int type;
640*055d4590SKeyi Gui    byte[] data;
641*055d4590SKeyi Gui    int offset, length;
642*055d4590SKeyi Gui};
643*055d4590SKeyi Gui</pre>
644*055d4590SKeyi Gui
645*055d4590SKeyi Gui<p>The chunk handlers accept and return them:
646*055d4590SKeyi Gui<pre class=prettyprint>
647*055d4590SKeyi Guipublic Chunk handleChunk(Chunk request)
648*055d4590SKeyi Gui</pre>
649*055d4590SKeyi Gui<p>The code is free to parse the chunk and generate a response in any
650*055d4590SKeyi Guiway it chooses.  Big-endian byte ordering is recommended but not mandatory.
651*055d4590SKeyi Gui<p>Chunk handlers will be notified when a DDM server connects or disconnects,
652*055d4590SKeyi Guiso that they can perform setup and cleanup operations:
653*055d4590SKeyi Gui<pre class=prettyprint>
654*055d4590SKeyi Guipublic void connected()
655*055d4590SKeyi Guipublic void disconnected()
656*055d4590SKeyi Gui</pre>
657*055d4590SKeyi Gui
658*055d4590SKeyi Gui<p>The method processes the request, formulates a response, and returns it.
659*055d4590SKeyi GuiIf the method returns null, an empty JDWP success message will be returned.
660*055d4590SKeyi Gui<p>The request/response interaction is essentially asynchronous in the
661*055d4590SKeyi Guiprotocol.  The packets are linked together with the JDWP message ID.
662*055d4590SKeyi Gui<p>[We could use ByteBuffer here instead of byte[], but it doesn't gain
663*055d4590SKeyi Guius much.  Wrapping a ByteBuffer around an array is easy.  We don't want
664*055d4590SKeyi Guito pass the full packet in because we could have multiple chunks in one
665*055d4590SKeyi Guirequest packet.  The DDM code needs to collect and aggregate the responses
666*055d4590SKeyi Guito all chunks into a single JDWP response packet.  Parties wanting to
667*055d4590SKeyi Guiwrite multiple chunks in response to a single chunk should send a null
668*055d4590SKeyi Guiresponse back and use "sendChunk()" to send the data independently.]
669*055d4590SKeyi Gui
670*055d4590SKeyi Gui<h3>Unsolicited event API</h3>
671*055d4590SKeyi Gui
672*055d4590SKeyi Gui<p>If a piece of code wants to send a chunk of data to the server at some
673*055d4590SKeyi Guiarbitrary time, it may do so with a method provided by
674*055d4590SKeyi Guiorg.apache.harmony.dalvik.DdmServer:
675*055d4590SKeyi Gui
676*055d4590SKeyi Gui<pre class=prettyprint>
677*055d4590SKeyi Guipublic static void sendChunk(Chunk chunk)
678*055d4590SKeyi Gui</pre>
679*055d4590SKeyi Gui
680*055d4590SKeyi Gui<p>There is no response or status code.  No exceptions are thrown.
681*055d4590SKeyi Gui
682*055d4590SKeyi Gui
683*055d4590SKeyi Gui<h2>Server API</h2>
684*055d4590SKeyi Gui
685*055d4590SKeyi Gui<p>This is similar to the client side in many ways, but makes extensive
686*055d4590SKeyi Guiuse of ByteBuffer in a perhaps misguided attempt to use java.nio.channels
687*055d4590SKeyi Guiand avoid excessive thread creation and unnecessary data copying.
688*055d4590SKeyi Gui
689*055d4590SKeyi Gui<p>Upon receipt of a packet, the server will identify it as one of:
690*055d4590SKeyi Gui<ol>
691*055d4590SKeyi Gui    <li>Message to be passed through to the debugger
692*055d4590SKeyi Gui    <li>Response to an earlier request
693*055d4590SKeyi Gui    <li>Unsolicited event packet
694*055d4590SKeyi Gui</ol>
695*055d4590SKeyi Gui<p>To handle (2), when messages are sent from the server to the client,
696*055d4590SKeyi Guithe message must be paired with a callback method.  The response might be
697*055d4590SKeyi Guidelayed for a while -- or might never arrive -- so the server can't block
698*055d4590SKeyi Guiwaiting for responses from the client.
699*055d4590SKeyi Gui<p>The chunk handlers look like this:
700*055d4590SKeyi Gui<pre class=prettyprint>
701*055d4590SKeyi Guipublic void handleChunk(Client client, int type,
702*055d4590SKeyi Gui    ByteBuffer data, boolean isReply, int msgId)
703*055d4590SKeyi Gui</pre>
704*055d4590SKeyi Gui<p>The arguments are:
705*055d4590SKeyi Gui<dl>
706*055d4590SKeyi Gui    <dt>client
707*055d4590SKeyi Gui    <dd>An object representing the client VM that send us the packet.
708*055d4590SKeyi Gui    <dt>type
709*055d4590SKeyi Gui    <dd>The 32-bit chunk type.
710*055d4590SKeyi Gui    <dt>data
711*055d4590SKeyi Gui    <dd>The data.  The data's length can be determined by calling data.limit().
712*055d4590SKeyi Gui    <dt>isReply
713*055d4590SKeyi Gui    <dd>Set to "true" if this was a reply to a message we sent earlier,
714*055d4590SKeyi Gui    "false" if the client sent this unsolicited.
715*055d4590SKeyi Gui    <dt>msgId
716*055d4590SKeyi Gui    <dd>The JDWP message ID.  Useful for connecting replies with requests.
717*055d4590SKeyi Gui</dl>
718*055d4590SKeyi Gui<p>If a handler doesn't like the contents of a packet, it should log an
719*055d4590SKeyi Guierror message and return.  If the handler doesn't recognize the packet at
720*055d4590SKeyi Guiall, it can call the superclass' handleUnknownChunk() method.
721*055d4590SKeyi Gui
722*055d4590SKeyi Gui<p>As with the client, the server code can be notified when clients
723*055d4590SKeyi Guiconnect or disconnect.  This allows the handler to send initialization
724*055d4590SKeyi Guicode immediately after a connect, or clean up after a disconnect.
725*055d4590SKeyi Gui<p>Data associated with a client can be stored in a ClientData object,
726*055d4590SKeyi Guiwhich acts as a general per-client dumping around for VM and UI state.
727*055d4590SKeyi Gui
728*055d4590SKeyi Gui
729*055d4590SKeyi Gui<P><BR>
730*055d4590SKeyi Gui
731*055d4590SKeyi Gui<HR>
732*055d4590SKeyi Gui
733*055d4590SKeyi Gui<address>Copyright &copy; 2007 The Android Open Source Project</address>
734*055d4590SKeyi Gui
735*055d4590SKeyi Gui</body>
736*055d4590SKeyi Gui</HTML>
737