OSDN Git Service

am 6e2d46fd: am 03a938bc: Merge "Fix -Xjitthreshold (for real this time)."
[android-x86/dalvik.git] / docs / debugger.html
1 <html>
2 <head>
3 <title>Dalvik Debugger Support</title>
4 </head>
5
6 <body>
7 <h1>Dalvik Debugger Support</h1>
8
9 <p>
10 The Dalvik virtual machine supports source-level debugging with many popular
11 development environments.  Any tool that allows remote debugging over JDWP
12 (the
13 <a href="http://java.sun.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html">
14 Java Debug Wire Protocol</a>) is expected work.  Supported debuggers
15 include jdb, Eclipse, IntelliJ, and JSwat.
16 </p><p>
17 The VM does not support tools based on JVMTI (Java Virtual
18 Machine Tool Interface).  This is a relatively intrusive approach that
19 relies on bytecode insertion, something the Dalvik VM does not currently
20 support.
21 </p><p>
22 Dalvik's implementation of JDWP also includes hooks for supporting
23 DDM (Dalvik Debug Monitor) features, notably as implemented by DDMS
24 (Dalvik Debug Monitor Server) and the Eclipse ADT plugin.  The protocol
25 and VM interaction is described in some detail
26 <a href="debugmon.html">here</a>.
27 </p><p>
28 All of the debugger support in the VM lives in the <code>dalvik/vm/jdwp</code>
29 directory, and is almost entirely isolated from the rest of the VM sources.
30 <code>dalvik/vm/Debugger.c</code> bridges the gap.  The goal in doing so
31 was to make it easier to re-use the JDWP code in other projects.
32 </p><p>
33
34
35 <h2>Implementation</h2>
36
37 <p>
38 Every VM that has debugging enabled starts a "JDWP" thread.  The thread
39 typically sits idle until DDMS or a debugger connects.  The thread is
40 only responsible for handling requests from the debugger; VM-initated
41 communication, such as notifying the debugger when the VM has stopped at
42 a breakpoint, are sent from the affected thread.
43 </p><p>
44 When the VM is started from the Android app framework, debugging is enabled
45 for all applications when the system property <code>ro.debuggable</code>
46 is set to </code>1</code> (use <code>adb shell getprop ro.debuggable</code>
47 to check it).  If it's zero, debugging can be enabled via the application's
48 manifest, which must include <code>android:debuggable="true"</code> in the
49 <code>&lt;application&gt;</code> element.
50
51 </p><p>
52 The VM recognizes the difference between a connection from DDMS and a
53 connection from a debugger (either directly or in concert with DDMS).
54 A connection from DDMS alone doesn't result in a change in VM behavior,
55 but when the VM sees debugger packets it allocates additional data
56 structures and may switch to a different implementation of the interpreter.
57 </p><p>
58 Pre-Froyo implementations of the Dalvik VM used read-only memory mappings
59 for all bytecode, which made it necessary to scan for breakpoints by
60 comparing the program counter to a set of addresses.  In Froyo this was
61 changed to allow insertion of breakpoint opcodes.  This allows the VM
62 to execute code more quickly, and does away with the hardcoded limit
63 of 20 breakpoints.  Even with this change, however, the debug-enabled
64 interpreter is much slower than the regular interpreter (perhaps 5x).
65 </p><p>
66 The JDWP protocol is stateless, so the VM handles individual debugger
67 requests as they arrive, and posts events to the debugger as they happen.
68 </p><p>
69
70
71 <h2>Debug Data</h2>
72 <p> Source code debug data, which includes mappings of source code to
73 bytecode and lists describing which registers are used to hold method
74 arguments and local variables, are optionally emitted by the Java compiler.
75 When <code>dx</code> converts Java bytecode to Dalvik bytecode, it must
76 also convert this debug data.
77 </p><p>
78 <code>dx</code> must also ensure that it doesn't perform operations
79 that confuse the debugger.  For example, re-using registers that hold
80 method arguments and the "<code>this</code>" pointer is allowed in
81 Dalvik bytecode if the values are never used or no longer needed.
82 This can be very confusing for the debugger (and the programmer)
83 since the values have method scope and aren't expected to disappear.  For
84 this reason, <code>dx</code> generates sub-optimal code in some situations
85 when debugging support is enabled.
86 </p><p>
87 Some of the debug data is used for other purposes; in particular, having
88 filename and line number data is necessary for generating useful exception
89 stack traces.  This data can be omitted by <code>dx</code> to make the DEX
90 file smaller.
91 </p><p>
92
93
94 <h2>Usage</h2>
95
96 <p>
97 The Dalvik VM supports many of the same command-line flags that other popular
98 desktop VMs do.  To start a VM with debugging enabled, you add a command-line
99 flag with some basic options.  The basic incantation looks something
100 like this:
101
102 <pre>-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y</pre>
103 or
104 <pre>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y</pre>
105
106 </p><p>
107 After the initial prefix, options are provided as name=value pairs.  The
108 options currently supported by the Dalvik VM are:
109 <dl>
110     <dt>transport (no default)</dt>
111     <dd>Communication transport mechanism to use.  Dalvik supports
112     TCP/IP sockets (<code>dt_socket</code>) and connection over USB
113     through ADB (<code>dt_android_adb</code>).
114     </dd>
115
116     <dt>server (default='n')</dt>
117     <dd>Determines whether the VM acts as a client or a server.  When
118     acting as a server, the VM waits for a debugger to connect to it.
119     When acting as a client, the VM attempts to connect to a waiting
120     debugger.
121     </dd>
122
123     <dt>suspend (default='n')</dt>
124     <dd>If set to 'y', the VM will wait for a debugger connection
125     before executing application code.  When the debugger connects (or
126     when the VM finishes connecting to the debugger), the VM tells the
127     debugger that it has suspended, and will not proceed until told
128     to resume.  If set to 'n', the VM just plows ahead.
129     </dd>
130
131     <dt>address (default="")</dt>
132     <dd>This must be <code>hostname:port</code> when <code>server=n</code>,
133     but can be just <code>port</code> when <code>server=y</code>.  This
134     specifies the IP address and port number to connect or listen to.
135     <br>
136     Listening on port 0 has a special meaning: try to
137     listen on port 8000; if that fails, try 8001, 8002, and so on.  (This
138     behavior is non-standard and may be removed from a future release.)
139     <br>This option has no meaning for <code>transport=dt_android_adb</code>.
140     </dd>
141
142     <dt>help (no arguments)</dt>
143     <dd>If this is the only option, a brief usage message is displayed.
144     </dd>
145
146     <dt>launch, onthrow, oncaught, timeout</dt>
147     <dd>These options are accepted but ignored.
148     </dd>
149 </dl>
150
151 </p><p>
152 To debug a program on an Android device using DDMS over USB, you could
153 use a command like this:
154 <pre>% dalvikvm -agentlib:jdwp=transport=dt_android_adb,suspend=y,server=y -cp /data/foo.jar Foo</pre>
155
156 This tells the Dalvik VM to run the program with debugging enabled, listening
157 for a connection from DDMS, and waiting for a debugger.  The program will show
158 up with an app name of "?" in the process list, because it wasn't started
159 from the Android application framework.  From here you would connect your
160 debugger to the appropriate DDMS listen port (e.g.
161 <code>jdb -attach localhost:8700</code> after selecting it in the app list).
162
163 </p><p>
164 To debug a program on an Android device using TCP/IP bridged across ADB,
165 you would first need to set up forwarding:
166 <pre>% adb forward tcp:8000 tcp:8000
167 % adb shell dalvikvm -agentlib:jdwp=transport=dt_socket,address=8000,suspend=y,server=y -cp /data/foo.jar Foo</pre>
168 and then <code>jdb -attach localhost:8000</code>.
169 </p><p>
170 (In the above examples, the VM will be suspended when you attach.  In jdb,
171 type <code>cont</code> to continue.)
172 </p><p>
173 The DDMS integration makes the <code>dt_android_adb</code> transport much
174 more convenient when debugging on an Android device, but when working with
175 Dalvik on the desktop it makes sense to use the TCP/IP transport.
176 </p><p>
177
178
179 <h2>Known Issues and Limitations</h2>
180
181 </p><p>
182 Most of the optional features JDWP allows are not implemented.  These
183 include field access watchpoints and better tracking of monitors.
184 </p><p>
185 Not all JDWP requests are implemented.  In particular, anything that
186 never gets emitted by the debuggers we've used is not supported and will
187 result in error messages being logged.  Support will be added when a
188 use case is uncovered.
189 </p><p>
190 &nbsp;
191 </p><p>
192 The debugger and garbage collector are somewhat loosely
193 integrated at present.  The VM currently guarantees that any object the
194 debugger is aware of will not be garbage collected until after the
195 debugger disconnects.  This can result in a build-up over time while the
196 debugger is connected.  For example, if the debugger sees a running
197 thread, the associated Thread object will not be collected, even after
198 the thread terminates.
199 </p><p>
200 The only way to "unlock" the references is to detach and reattach the
201 debugger.
202 </p><p>
203 &nbsp;
204 </p><p>
205 The translation from Java bytecode to Dalvik bytecode may result in
206 identical sequences of instructions being combined.  This can make it
207 look like the wrong bit of code is being executed.  For example:
208 <pre>    int test(int i) {
209         if (i == 1) {
210             return 0;
211         }
212         return 1;
213     }</pre>
214 The Dalvik bytecode uses a common <code>return</code> instruction for both
215 <code>return</code> statements, so when <code>i</code> is 1 the debugger
216 will single-step through <code>return 0</code> and then <code>return 1</code>.
217 </p><p>
218 &nbsp;
219 </p><p>
220 Dalvik handles synchronized methods differently from other VMs.
221 Instead of marking a method as <code>synchronized</code> and expecting
222 the VM to handle the locks, <code>dx</code> inserts a "lock"
223 instruction at the top of the method and an "unlock" instruction in a
224 synthetic <code>finally</code> block.  As a result, when single-stepping
225 a <code>return</code> statement, the "current line" cursor may jump to
226 the last line in the method.
227 </p><p>
228 This can also affect the way the debugger processes exceptions.  The
229 debugger may decide to break on an
230 exception based on whether that exception is "caught" or "uncaught".  To
231 be considered uncaught, there must be no matching <code>catch</code> block
232 or <code>finally</code> clause between the current point of execution and
233 the top of the thread.  An exception thrown within or below a synchronized
234 method will always be considered "caught", so the debugger won't stop
235 until the exception is re-thrown from the synthetic <code>finally</code> block.
236 </p><p>
237
238
239 <address>Copyright &copy; 2009 The Android Open Source Project</address>
240 </p>
241
242 </body>
243 </html>