AI 148118: 2 new debugging docs.
Automated import of CL 148118
diff --git a/pdk/docs/guide/debugging_gdb.jd b/pdk/docs/guide/debugging_gdb.jd
new file mode 100755
index 0000000..fe63307
--- /dev/null
+++ b/pdk/docs/guide/debugging_gdb.jd
@@ -0,0 +1,143 @@
+page.title=Debugging with GDB
+pdk.version=1.0
+@jd:body
+
+<a name="toc"/>
+<div style="padding:10px"> <a href="#intro">Introduction</a><br/>
+ <a href="#gdb">Running gdb on the desktop</a><br/>
+ <div style="padding-left:40px"> <a href="#gdbShort">Short Instructions</a><br/>
+ <a href="#gdbDetailed">Detailed Instructions</a><br/>
+ </div>
+ <a href="#justInTime">Just-In-Time Debug Feature</a><br/>
+</div>
+<a name="intro"></a>
+<h3>Introduction</h3>
+<p>The current version of <code>envsetup.sh</code> has a <code>gdbclient</code> command that handles much of the setup. For example, to attach to the
+ already-running <code>globaltime</code> application, execute the following, making sure that: 1) you do this from the same window used to build the software on the device you are debugging and 2) verify that the symbols in the object files in the build tree match up with what is installed on the device or emulator.</p>
+<pre class="prettify">
+gdbclient app_process :5039 globaltime
+</pre>
+<a name="gdbShort"></a>
+<h4>Short Instructions</h4>
+<p>Android runs <code>gdbserver</code> on the device and an ARM aware <code>gdb</code>, named <code>arm-eabi-gdb</code>, on the desktop machine.</p>
+<ol>
+ <li>First you need to
+ run <code>gdbserver</code> on the device:<BR>
+ <pre class="prettify">
+ gdbserver :5039 /system/bin/<i>executable</i>
+ </pre>
+ <BR>
+ The <code>:5039</code> tells gdbserver to listen on port 5039 on the localhost, which adb bridges from the host to the device. <code>executable</code> represents the command to debug, a common one being runtime -s which starts the entire system all running in a single process. <br>
+ <br>
+ </li>
+ <li>Launch <code>gdb</code> on the desktop.
+ This can be
+ done easily with the following command in the shell from which you built:
+ <pre class="prettify">
+gdbclient <i>executable</i>
+</pre>
+ </li>
+</ol>
+<p>At this point <code>gdb</code> will connect with your device
+ and you should be
+ able to enter <code>c</code> to have the device start executing inside of the
+ desktop <code>gdb</code> session.</p>
+<a name="gdbDetailed"></a>
+<h4>Detailed Instructions</h4>
+<p>If the short instructions don't work, these detailed instructions should:
+<ol>
+ <li>On the device, launch a new command:
+ <pre class="prettify">gdbserver :5039 /system/bin/<i>executable</i></pre>
+ or attach to an existing process:
+ <pre class="prettify">gdbserver :5039 --attach <i>pid</i></pre>
+ </li>
+ <li>On your workstation, forward port 5039 to the device with adb:
+ <pre class="prettify">adb forward tcp:5039 tcp:5039</pre>
+ </li>
+ <li>Start a special version of <code>gdb</code> that lives in the "prebuilt" area of the source tree: <br>
+ <code>prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-eabi-gdb</code> (for Linux) <br>
+ <code>prebuilt/darwin-x86/toolchain-eabi-4.2.1/bin/arm-eabi-gdb</code> (for Darwin) </li>
+ <li>If you can't find either special version of <code>gdb</code>, run <code>find prebuilt -name arm-eabi-gdb</code> in your source tree to find and run the latest version:
+ <pre class="prettify">
+prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-eabi-gdb out/target/product/<i>product-name</i>/symbols/system/bin/<i>executable</i>
+</pre>
+ <BR>
+ Where <i>product-name</i> is the name of the device product that you're building (for example, <code>sooner</code>),
+ and <i>executable</i> is the program to debug (usually <code>app_process</code> for an application).<br>
+ <br>
+ Make sure to use the copy of the executable in the symbols directory, not the
+ primary android directory, because the one in the primary directory has
+ been stripped of its debugging information.</li>
+ <li>In <code>gdb</code>, Tell <code>gdb</code> where to find the shared libraries that will get loaded:
+ <pre class="prettify">
+set solib-absolute-prefix /<i>absolute-source-path</i>/out/target/product/<i>product-name</i>/symbols
+set solib-search-path /<i>absolute-source-path</i>/out/target/product/<i>product-name</i>/symbols/system/lib
+</pre>
+ <BR>
+ <i>absolute-source-path</i> is the path to your source tree; for example, <code>/work/device</code> or <code>/Users/hoser/android/device</code>.<BR>
+ <i>product-name</i> is the same as above; for example, <code>sooner</code>. <BR>
+ <BR>
+ Make sure you specify the correct directories—<code>gdb</code> may not tell you if you make a mistake.</li>
+ <li>Connect to the device by issuing the <code>gdb</code> command:<BR>
+ <pre class="prettify">
+target remote :5039
+</pre>
+ <BR>
+ <BR>
+ The <code>:5039</code> tells <code>gdb</code> to connect to the localhost port 5039, which is bridged to the device by <code>adb</code>.<BR>
+ <BR>
+ You may need to inspire gdb to load some symbols by typing:
+ <pre class="prettify">shared</pre>
+ </li>
+</ol>
+<p>You should be connected and able to debug as you normally would. You can ignore the error about not
+ finding the location for the thread creation breakpoint. It will be found when
+ the linker loads <code>libc</code> into your process before hitting <code>main()</code>. Also note that
+ the <code>gdb</code> remote protocol doesn't have a way for the device to
+ tell the host about
+ newly created threads so you will not always see notifications about newly
+ created threads. Info about other threads will be queried from the
+ device when a
+ breakpoint is hit or you ask for it by running info thread. <a name="justInTime"></a>
+<h3>Just-In-Time Debug Feature</h3>
+If you see the red LED flashing it means a process is in that new
+state (crashed and waiting for GDB connection). If this happens to the
+system process, most likely your device will be frozen at this point. <strong>Do not press the home key</strong>. Bring the device to someone who can
+debug native crashes and ask for advice.
+If you're in the field and just want your device to continue as it
+would have without this feature (like cylonning), press home (a
+tombstone will be recorded as usual).
+
+To enable a process to be debugged this way, you need to set a property:
+<pre class="prettify">
+adb shell setprop debug.db.uid 10000
+</pre>
+and all processes with a <code>uid <= 10000</code> will be trapped in this
+manner. When one of them crashes, the tombstone is processed as usual, an explicit message is printed into the log, and the red LED starts
+flashing waiting for the Home key to be depressed (in which case it
+continues execution as usual).
+<pre class="prettify">
+I/DEBUG ( 27): ********************************************************
+I/DEBUG ( 27): * process 82 crashed. debuggerd waiting for gdbserver
+I/DEBUG ( 27): *
+I/DEBUG ( 27): * adb shell gdbserver :port --attach 82 &
+I/DEBUG ( 27): *
+I/DEBUG ( 27): * and press the HOME key.
+I/DEBUG ( 27): ********************************************************
+</pre>
+<p>When you see the entry above, make sure <code>adb</code> is forwarding port 5039 (you only need to do this once,
+ unless the ADB server dies) and execute:</p>
+<pre class="prettify">% adb forward tcp:5039 tcp:5039</pre>
+Execute the line shown in the debug output, substituting 5039 for the proper <code>port</code>:
+<pre class="prettify">
+% adb shell gdbserver :5039 --attach 82 &
+</pre>
+<p>If the crashing process is based off zygote (that is, system_server and all
+ applications), the default values for the <code>gdbclient</code> command, <code>app_process</code> binary and port <code>5039</code>, are correct, so you can execute:</p>
+<pre class="prettify">
+% cd <top of device source tree>
+% gdbclient
+</pre>
+<p>Otherwise you need to determine the path of the crashing binary and follow the
+ steps as mentioned above (for example, <code>gdbclient hoser :5039</code> if
+ the <code>hoser</code> command has failed).</p>
\ No newline at end of file
diff --git a/pdk/docs/guide/debugging_native.jd b/pdk/docs/guide/debugging_native.jd
new file mode 100755
index 0000000..95ef6a7
--- /dev/null
+++ b/pdk/docs/guide/debugging_native.jd
@@ -0,0 +1,286 @@
+page.title=Debugging Native Code
+pdk.version=1.0
+@jd:body
+
+
+<a name="toc"/>
+<div style="padding:10px">
+ <a href="#Capturing_logs">Capturing logs</a><br/>
+ <a href="#Debug_Scenarios">Debug Scenarios</a><br/>
+ <div style="padding-left:40px">
+ <a href="#Crash_but_no_exit_stuck">Crash but no exit...stuck</a><br/>
+ <a href="#Blocked_in_a_syscall">Blocked in a syscall</a><br/>
+ <a href="#Crash_in_C_C_code">Crash in C / C++ code</a>
+ </div>
+</div>
+
+
+<a name="Capturing_logs"></a><h2>Capturing logs</h2>
+
+<p>To capture log output:</p>
+<ol>
+<li> Produce a process list with <code>ps</code> (<code>ps -t</code> if you want verbose thread feedback).</li>
+<li> Dump kernel messages with <code>dmesg</code>.</li>
+<li> Get verbose log messages with <code>logcat '*:v' &</code> (running in bg with & is important).</li>
+
+</ol>
+
+<a name="Debug_Scenarios"></a><h2>Debug Scenarios</h2>
+<pre class="prettify">
+ # command to device shell (via adb)
+ % command to host pc shell
+</pre>
+<p>
+</p>
+
+<a name="Crash_but_no_exit_stuck"></a><h3>Crash but no exit...stuck</h3>
+<pre class="prettify">
+>>> gtalk app crashed but did not actually exit or seems stuck
+>>> let's check the debug logs and see if there's anything to see:
+
+# logcat &
+
+...
+E/WindowManager( 182): Window client android.util.BinderProxy@4089f948 has died!! Removing window.
+W/WindowManager( 182): **** WINDOW CLIENT android.view.WindowProxy@40882248 DIED!
+W/ActivityManager( 182): **** APPLICATION com.google.android.gtalk DIED!
+I/ServiceManager( 257): Executing: /android/bin/app_process (link=/tmp/android-servicemanager/com.google.android.gtalk, wrapper=/tmp/android-servi
+cemanager/com.google.android.gtalk)
+I/appproc ( 257): App process is starting with pid=257, class=android/activity/ActivityThread.
+I/ ( 257): java.io.FileDescriptor: class initialization
+I/SurfaceFlinger.HW( 182): About to give-up screen
+I/SurfaceFlinger.HW( 182): screen given-up
+I/SurfaceFlinger.HW( 182): Screen about to return
+I/SurfaceFlinger.HW( 182): screen returned
+I/SurfaceFlinger.HW( 182): About to give-up screen
+I/SurfaceFlinger.HW( 182): screen given-up
+I/SurfaceFlinger.HW( 182): Screen about to return
+...
+
+>>> looks like the system launched a replacement gtalk process
+>>> but it is stuck somehow
+
+# ps
+PID PPID VSIZE RSS WCHAN PC NAME
+257 181 45780 5292 ffffffff 53030cb4 S com.google.andr
+
+>>> gtalk's PC is at 53030cb4
+>>> look at the memory map to find out what lib is 0x53......
+
+# cat /proc/257/maps
+...
+51000000-5107c000 rwxp 00000000 1f:03 619 /android/lib/libutils.so
+52000000-52013000 rwxp 00000000 1f:03 639 /android/lib/libz.so
+53000000-53039000 rwxp 00000000 1f:03 668 /android/lib/libc.so
+53039000-53042000 rw-p 53039000 00:00 0
+54000000-54002000 rwxp 00000000 1f:03 658 /android/lib/libstdc++.so
+...
+
+>>> let's disassemble libc and find out where we are?!
+
+% prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-elf-objdump -d out/target/product/sooner/symbols/android/lib/libc.so
+
+00030ca4 <__futex_wait>:
+ 30ca4: e1a03002 mov r3, r2
+ 30ca8: e1a02001 mov r2, r1
+ 30cac: e3a01000 mov r1, #0 ; 0x0
+ 30cb0: ef9000f0 swi 0x009000f0
+ 30cb4: e12fff1e bx lr
+</pre>
+
+<a name="Blocked_in_a_syscall"></a><h4>Blocked in a syscall</h4>
+
+<pre class="prettify">
+>>> we're blocked in a syscall, let's see what gdb can show us
+>>> (we could have done this first if we wanted to)
+
+>>> tell adb to forward the GDB port
+% adb forward tcp:5039 tcp:5039
+
+>>> start gdb server and attach to process 257 (from example above)
+# gdbserver :5039 --attach 257 &
+Attached; pid = 257
+Listening on port 5039
+
+% prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-elf-gdb out/target/product/sooner/system/bin/app_process
+(gdb) set solib-absolute-prefix /work/android/device/out/target/product/sooner/symbols
+(gdb) set solib-search-path /work/android/device/out/target/product/sooner/symbols/android/lib
+(gdb) target remote :5039
+Remote debugging using :5039
+0x53030cb4 in ?? ()
+Current language: auto; currently asm
+
+>>> Don't let other threads get scheduled while we're debugging.
+>>> You should "set scheduler-locking off" before issuing a "continue",
+>>> or else your thread may get stuck on a futex or other
+>>> spinlock because no other thread can release it.
+(gdb) set scheduler-locking on
+
+>>> Ignore SIGUSR1 if you're using JamVM. Shouldn't hurt if you're not.
+(gdb) handle SIGUSR1 noprint
+
+(gdb) where
+#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+#1 0x53010eb8 in pthread_cond_timedwait (cond=0x12081c, mutex=0x120818, abstime=0xffffffff)
+ at system/klibc/android/pthread.c:490
+#2 0x6b01c848 in monitorWait (mon=0x120818, self=0x6b039ba4, ms=0, ns=0) at extlibs/jamvm-1.4.1/src/lock.c:194
+#3 0x6b01d1d8 in objectWait (obj=0x408091c0, ms=0, ns=0) at extlibs/jamvm-1.4.1/src/lock.c:420
+#4 0x6b01d4c8 in jamWait (clazz=0xfffffffc, mb=0x0, ostack=0x2e188) at extlibs/jamvm-1.4.1/src/natives.c:91
+#5 0x6b013b2c in resolveNativeWrapper (clazz=0x408001d0, mb=0x41798, ostack=0x2e188) at extlibs/jamvm-1.4.1/src/dll.c:236
+#6 0x6b015c04 in executeJava () at extlibs/jamvm-1.4.1/src/interp.c:2614
+#7 0x6b01471c in executeMethodVaList (ob=0x0, clazz=0x40808f20, mb=0x12563c, jargs=0xbe9229f4)
+ at extlibs/jamvm-1.4.1/src/execute.c:91
+#8 0x6b01bcd0 in Jam_CallStaticVoidMethod (env=0xfffffffc, klass=0x0, methodID=0x12563c)
+ at extlibs/jamvm-1.4.1/src/jni.c:1063
+#9 0x58025b2c in android::AndroidRuntime::callStatic (this=0xfffffffc,
+ className=0xbe922f0a "android/activity/ActivityThread", methodName=0x57000b7c "main")
+ at libs/android_runtime/AndroidRuntime.cpp:215
+#10 0x57000504 in android::app_init (className=0xbe922f0a "android/activity/ActivityThread")
+ at servers/app/library/app_init.cpp:20
+#11 0x000089b0 in android::sp<android::ProcessState>::~sp ()
+#12 0x000089b0 in android::sp<android::ProcessState>::~sp ()
+Previous frame identical to this frame (corrupt stack?)
+
+(gdb) info threads
+ 7 thread 263 __ioctl () at system/klibc/syscalls/__ioctl.S:12
+ 6 thread 262 accept () at system/klibc/syscalls/accept.S:12
+ 5 thread 261 __futex_wait () at system/klibc/android/atomics_arm.S:88
+ 4 thread 260 __futex_wait () at system/klibc/android/atomics_arm.S:88
+ 3 thread 259 __futex_wait () at system/klibc/android/atomics_arm.S:88
+ 2 thread 258 __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
+ 1 thread 257 __futex_wait () at system/klibc/android/atomics_arm.S:88
+
+
+(gdb) thread 7
+[Switching to thread 7 (thread 263)]#0 __ioctl () at system/klibc/syscalls/__ioctl.S:12
+12 movs r0, r0
+(gdb) bt
+#0 __ioctl () at system/klibc/syscalls/__ioctl.S:12
+#1 0x53010704 in ioctl (fd=-512, request=-1072143871) at system/klibc/android/ioctl.c:22
+#2 0x51040ac0 in android::IPCThreadState::talkWithDriver (this=0x1207b8, doReceive=true) at RefBase.h:83
+#3 0x510418a0 in android::IPCThreadState::joinThreadPool (this=0x1207b8, isMain=false)
+ at libs/utils/IPCThreadState.cpp:343
+#4 0x51046004 in android::PoolThread::threadLoop (this=0xfffffe00) at libs/utils/ProcessState.cpp:52
+#5 0x51036428 in android::Thread::_threadLoop (user=0xfffffe00) at libs/utils/Threads.cpp:1100
+#6 0x58025c68 in android::AndroidRuntime::javaThreadShell (args=0x105ffe28) at libs/android_runtime/AndroidRuntime.cpp:540
+
+(gdb) thread 6
+[Switching to thread 6 (thread 262)]#0 accept () at system/klibc/syscalls/accept.S:12
+12 movs r0, r0
+(gdb) bt
+#0 accept () at system/klibc/syscalls/accept.S:12
+#1 0x6b0334e4 in jdwpAcceptConnection (state=0xfffffe00) at extlibs/jamvm-1.4.1/jdwp/JdwpNet.c:213
+#2 0x6b032660 in jdwpThreadEntry (self=0x4d020) at extlibs/jamvm-1.4.1/jdwp/JdwpMain.c:37
+#3 0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
+
+(gdb) thread 5
+[Switching to thread 5 (thread 261)]#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+88 bx lr
+(gdb) bt
+#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+#1 0x53010f48 in pthread_cond_timeout (cond=0x6b039b64, mutex=0x6b039b60, msecs=0) at system/klibc/android/pthread.c:513
+#2 0x6b01c8d0 in monitorWait (mon=0x6b039b60, self=0x4d400, ms=1000, ns=272629312) at extlibs/jamvm-1.4.1/src/lock.c:183
+#3 0x6b022084 in threadSleep (thread=0x4d400, ms=1000, ns=272629312) at extlibs/jamvm-1.4.1/src/thread.c:215
+#4 0x6b00d4fc in asyncGCThreadLoop (self=0x4d400) at extlibs/jamvm-1.4.1/src/alloc.c:1179
+#5 0x6b022c2c in shell (args=0x4d480) at extlibs/jamvm-1.4.1/src/thread.c:629
+
+(gdb) thread 4
+[Switching to thread 4 (thread 260)]#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+88 bx lr
+(gdb) bt
+#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+#1 0x53010eb8 in pthread_cond_timedwait (cond=0x6b039934, mutex=0x6b039930, abstime=0x0)
+ at system/klibc/android/pthread.c:490
+#2 0x6b00b3ec in referenceHandlerThreadLoop (self=0x4d360) at extlibs/jamvm-1.4.1/src/alloc.c:1247
+#3 0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
+
+(gdb) thread 3
+[Switching to thread 3 (thread 259)]#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+88 bx lr
+(gdb) bt
+#0 __futex_wait () at system/klibc/android/atomics_arm.S:88
+#1 0x53010eb8 in pthread_cond_timedwait (cond=0x6b03992c, mutex=0x6b039928, abstime=0x0)
+ at system/klibc/android/pthread.c:490
+#2 0x6b00b1dc in finalizerThreadLoop (self=0x4d8e0) at extlibs/jamvm-1.4.1/src/alloc.c:1238
+#3 0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
+
+(gdb) thread 2
+[Switching to thread 2 (thread 258)]#0 __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
+12 movs r0, r0
+(gdb) bt
+#0 __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
+#1 0x6b023814 in dumpThreadsLoop (self=0x51b98) at extlibs/jamvm-1.4.1/src/thread.c:1107
+#2 0x6b022c2c in shell (args=0x51b58) at extlibs/jamvm-1.4.1/src/thread.c:629
+</pre>
+
+<a name="Crash_in_C_C_code"></a><h3>Crash in C / C++ code</h3>
+<p>If it crashes, connect with <code>aproto</code> and run <code>logcat</code> on the device. You should see output like this:</p>
+
+<pre class="prettify">
+I/ActivityManager( 188): Starting activity: Intent { component=com.android.calendar.MonthScreen }
+I/ActivityManager( 188): Starting application com.android.calendar to host activity com.android.calendar.MonthScree
+n
+I/ServiceManager( 417): Executing: /android/bin/app_process (link=/android/bin/app_process, wrapper=/android/bin/app_process)
+I/DEBUG: -- observer of pid 417 starting --
+I/appproc ( 417): App process is starting with pid=417, class=android/activity/ActivityThread.
+I/DEBUG: -- observer of pid 417 exiting --
+I/DEBUG: -- observer of pid 420 starting --
+I/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+I/DEBUG: pid: 373, tid: 401 >>> android.content.providers.pim <<<
+I/DEBUG: signal 11 (SIGSEGV), fault addr 00000000
+I/DEBUG: r0 ffffffff r1 00000000 r2 00000454 r3 002136d4
+I/DEBUG: r4 002136c0 r5 40804810 r6 0022dc70 r7 00000010
+I/DEBUG: r8 0020a258 r9 00000014 10 6b039074 fp 109ffcf8
+I/DEBUG: ip 6b039e90 sp 109ffc0c lr 580239f0 pc 6b0156a0
+I/DEBUG: #01 pc 6b0156a0 /android/lib/libjamvm.so
+I/DEBUG: #01 lr 580239f0 /android/lib/libandroid_runtime.so
+I/DEBUG: #02 pc 6b01481c /android/lib/libjamvm.so
+I/DEBUG: #03 pc 6b0148a4 /android/lib/libjamvm.so
+I/DEBUG: #04 pc 6b00ebc0 /android/lib/libjamvm.so
+I/DEBUG: #05 pc 6b02166c /android/lib/libjamvm.so
+I/DEBUG: #06 pc 6b01657c /android/lib/libjamvm.so
+I/DEBUG: #07 pc 6b01481c /android/lib/libjamvm.so
+I/DEBUG: #08 pc 6b0148a4 /android/lib/libjamvm.so
+I/DEBUG: #09 pc 6b0235c0 /android/lib/libjamvm.so
+I/DEBUG: #10 pc 5300fac4 /android/lib/libc.so
+I/DEBUG: #11 pc 5300fc5c /android/lib/libc.so
+I/DEBUG: -- observer of pid 373 exiting --
+I/DEBUG: -- observer of pid 423 starting --
+</pre>
+
+<p>If debugging output indicates an error in C or C++ code, the addresses aren't particularly useful, but the debugging symbols aren't present on the device. Use the "stack" tool to convert these addresses to files and line numbers, for example:</p>
+
+<pre class="prettify">
+pid: 373, tid: 401 >>> android.content.providers.pim <<<
+
+ signal 11 (SIGSEGV), fault addr 00000000
+ r0 ffffffff r1 00000000 r2 00000454 r3 002136d4
+ r4 002136c0 r5 40804810 r6 0022dc70 r7 00000010
+ r8 0020a258 r9 00000014 10 6b039074 fp 109ffcf8
+ r8 0020a258 r9 00000014 10 6b039074 fp 109ffcf8
+
+ ADDR FUNCTION FILE:LINE
+ 6b0156a0 executeJava extlibs/jamvm-1.4.1/src/interp.c:2674
+ 580239f0 android_util_Parcel_freeBuffer libs/android_runtime/android_util_Binder.cpp:765
+ 6b01481c executeMethodVaList extlibs/jamvm- 1.4.1/src/execute.c:91
+ 6b0148a4 executeMethodArgs extlibs/jamvm-1.4.1/src/execute.c:67
+ 6b00ebc0 initClass extlibs/jamvm-1.4.1/src/class.c:1124
+ 6b02166c resolveMethod extlibs/jamvm- 1.4.1/src/resolve.c:197
+ 6b01657c executeJava extlibs/jamvm-1.4.1/src/interp.c:2237
+ 6b01481c executeMethodVaList extlibs/jamvm-1.4.1/src/execute.c:91
+ 6b0148a4 executeMethodArgs extlibs/jamvm- 1.4.1/src/execute.c:67
+ 6b0235c0 threadStart extlibs/jamvm-1.4.1/src/thread.c:355
+ 5300fac4 __thread_entry system/klibc/android/pthread.c:59
+ 5300fc5c pthread_create system/klibc/android/pthread.c:182
+</pre>
+
+<p>If you save the debug spew into a file called <code>out.txt</code>, you can pass that to the tool, like this:
+</p>
+
+<pre class="prettify">
+./tools/stack out.txt
+</pre>
+
+<p>Or you can run <code>logcat</code> without any parameters and it will read from <code>stdin</code>. You can then paste output into the terminal or pipe it. Run <code>logcat</code> from the top of the tree in the environment in which you do builds so that the application can determine relative paths to the toolchain to use to decode the object files.
+</body>
+</html>