Home | History | Annotate | Download | only in porting
      1 page.title=Debugging Native Code
      2 pdk.version=1.0
      3 doc.type=porting
      4 @jd:body
      5 
      6 
      7 <div id="qv-wrapper">
      8 <div id="qv">
      9 <h2>In this document</h2>
     10 <a name="toc"/>
     11 <ul>
     12 <li><a href="#Capturing_logs">Capturing logs</a></li>
     13 <li><a href="#Debug_Scenarios">Debug Scenarios</a></li>
     14 </ul>
     15 </div>
     16 </div>
     17 
     18 <a name="Capturing_logs"></a><h3>Capturing logs</h3>
     19 
     20 <p>To capture log output:</p>
     21 <ol>
     22 <li> Produce a process list with <code>ps</code>   (<code>ps -t</code> if you want verbose thread feedback).</li>
     23 <li> Dump kernel messages with <code>dmesg</code>.</li>
     24 <li> Get verbose log messages with <code>logcat '*:v' &amp;</code>   (running in bg with &amp; is important).</li>
     25 
     26 </ol>
     27 
     28 <a name="Debug_Scenarios"></a><h3>Debug Scenarios</h3>
     29 <pre class="prettify">
     30   # command to device shell (via adb)
     31   % command to host pc shell
     32 </pre>
     33 <p>
     34 </p>
     35 
     36 <a name="Crash_but_no_exit_stuck"></a><h4>Crash but no exit...stuck</h4>
     37 
     38 <p>In this scenario, the GTalk app crashed but did not actually exit or seems stuck. Check the debug logs to see if there is anything unusual: </p>
     39 
     40 <pre class="prettify">
     41 # logcat &amp;
     42 
     43 ...
     44 E/WindowManager(  182): Window client android.util.BinderProxy@4089f948 has died!!  Removing window.
     45 W/WindowManager(  182): **** WINDOW CLIENT android.view.WindowProxy@40882248 DIED!
     46 W/ActivityManager(  182): **** APPLICATION com.google.android.gtalk DIED!
     47 I/ServiceManager(  257): Executing: /android/bin/app_process (link=/tmp/android-servicemanager/com.google.android.gtalk, wrapper=/tmp/android-servi
     48 cemanager/com.google.android.gtalk)
     49 I/appproc (  257): App process is starting with pid=257, class=android/activity/ActivityThread.
     50 I/        (  257): java.io.FileDescriptor: class initialization
     51 I/SurfaceFlinger.HW(  182): About to give-up screen
     52 I/SurfaceFlinger.HW(  182): screen given-up
     53 I/SurfaceFlinger.HW(  182): Screen about to return
     54 I/SurfaceFlinger.HW(  182): screen returned
     55 I/SurfaceFlinger.HW(  182): About to give-up screen
     56 I/SurfaceFlinger.HW(  182): screen given-up
     57 I/SurfaceFlinger.HW(  182): Screen about to return
     58 ...
     59 </pre>
     60 
     61 <p>
     62 The logs indicate that the system launched a replacement GTalk process but that it got stuck somehow:
     63 </p>
     64 
     65 <pre class="prettify">
     66 # ps
     67 PID   PPID  VSIZE RSS   WCHAN    PC         NAME
     68 257   181   45780 5292  ffffffff 53030cb4 S com.google.andr
     69 </pre>
     70 
     71 <p>
     72 GTalk's PC is at 53030cb4. Look at the memory map to find out what lib is 0x53......
     73 </p>
     74 
     75 <pre class="prettify">
     76 # cat /proc/257/maps
     77 ...
     78 51000000-5107c000 rwxp 00000000 1f:03 619        /android/lib/libutils.so
     79 52000000-52013000 rwxp 00000000 1f:03 639        /android/lib/libz.so
     80 53000000-53039000 rwxp 00000000 1f:03 668        /android/lib/libc.so
     81 53039000-53042000 rw-p 53039000 00:00 0
     82 54000000-54002000 rwxp 00000000 1f:03 658        /android/lib/libstdc++.so
     83 ...
     84 </pre>
     85 
     86 <p>
     87 Disassemble <code>libc</code> to figure out what is going on:
     88 </p>
     89 
     90 <pre class="prettify">
     91 % prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-elf-objdump -d out/target/product/sooner/symbols/android/lib/libc.so
     92 
     93 00030ca4 &lt;__futex_wait&gt;:
     94   30ca4:       e1a03002        mov     r3, r2
     95   30ca8:       e1a02001        mov     r2, r1
     96   30cac:       e3a01000        mov     r1, #0  ; 0x0
     97   30cb0:       ef9000f0        swi     0x009000f0
     98   30cb4:       e12fff1e        bx      lr
     99 </pre>
    100 
    101 <a name="Blocked_in_a_syscall"></a><h4>Blocked in a syscall</h4>
    102 
    103 <p>
    104 In this scenario, the system is blocked in a syscall. To debug using <code>gdb</code>, first tell <code>adb</code> to forward the <code>gdb</code> port:
    105 </p>
    106 
    107 <pre class="prettify">
    108 
    109 % adb forward tcp:5039 tcp:5039
    110 </pre>
    111 
    112 <p>
    113 Start the <code>gdb</code> server and attach to process 257 (as demonstrated in the previous example):
    114 </p>
    115 
    116 <pre class="prettify">
    117 # gdbserver :5039 --attach 257 &amp;
    118 Attached; pid = 257
    119 Listening on port 5039
    120 
    121 % prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-elf-gdb out/target/product/sooner/system/bin/app_process
    122 (gdb) set solib-absolute-prefix /work/android/device/out/target/product/sooner/symbols
    123 (gdb) set solib-search-path /work/android/device/out/target/product/sooner/symbols/android/lib
    124 (gdb) target remote :5039
    125 Remote debugging using :5039
    126 0x53030cb4 in ?? ()
    127 Current language:  auto; currently asm
    128 </pre>
    129 
    130 <p>
    131 Don't let other threads get scheduled while we're debugging.
    132 You should "set scheduler-locking off" before issuing a "continue", or else your thread may get stuck on a futex or other
    133 spinlock because no other thread can release it.
    134 </p>
    135 
    136 <pre class="prettify">
    137 (gdb) set scheduler-locking on
    138 </pre>
    139 
    140 <p>
    141 Ignore SIGUSR1 if you're using JamVM.  Shouldn't hurt if you're not.
    142 </p>
    143 
    144 <pre class="prettify">
    145 (gdb) handle SIGUSR1 noprint
    146 
    147 (gdb) where
    148 #0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    149 #1  0x53010eb8 in pthread_cond_timedwait (cond=0x12081c, mutex=0x120818, abstime=0xffffffff)
    150    at system/klibc/android/pthread.c:490
    151 #2  0x6b01c848 in monitorWait (mon=0x120818, self=0x6b039ba4, ms=0, ns=0) at extlibs/jamvm-1.4.1/src/lock.c:194
    152 #3  0x6b01d1d8 in objectWait (obj=0x408091c0, ms=0, ns=0) at extlibs/jamvm-1.4.1/src/lock.c:420
    153 #4  0x6b01d4c8 in jamWait (clazz=0xfffffffc, mb=0x0, ostack=0x2e188) at extlibs/jamvm-1.4.1/src/natives.c:91
    154 #5  0x6b013b2c in resolveNativeWrapper (clazz=0x408001d0, mb=0x41798, ostack=0x2e188) at extlibs/jamvm-1.4.1/src/dll.c:236
    155 #6  0x6b015c04 in executeJava () at extlibs/jamvm-1.4.1/src/interp.c:2614
    156 #7  0x6b01471c in executeMethodVaList (ob=0x0, clazz=0x40808f20, mb=0x12563c, jargs=0xbe9229f4)
    157    at extlibs/jamvm-1.4.1/src/execute.c:91
    158 #8  0x6b01bcd0 in Jam_CallStaticVoidMethod (env=0xfffffffc, klass=0x0, methodID=0x12563c)
    159    at extlibs/jamvm-1.4.1/src/jni.c:1063
    160 #9  0x58025b2c in android::AndroidRuntime::callStatic (this=0xfffffffc,
    161    className=0xbe922f0a "android/activity/ActivityThread", methodName=0x57000b7c "main")
    162    at libs/android_runtime/AndroidRuntime.cpp:215
    163 #10 0x57000504 in android::app_init (className=0xbe922f0a "android/activity/ActivityThread")
    164    at servers/app/library/app_init.cpp:20
    165 #11 0x000089b0 in android::sp&lt;android::ProcessState&gt;::~sp ()
    166 #12 0x000089b0 in android::sp&lt;android::ProcessState&gt;::~sp ()
    167 Previous frame identical to this frame (corrupt stack?)
    168 
    169 (gdb) info threads
    170  7 thread 263  __ioctl () at system/klibc/syscalls/__ioctl.S:12
    171  6 thread 262  accept () at system/klibc/syscalls/accept.S:12
    172  5 thread 261  __futex_wait () at system/klibc/android/atomics_arm.S:88
    173  4 thread 260  __futex_wait () at system/klibc/android/atomics_arm.S:88
    174  3 thread 259  __futex_wait () at system/klibc/android/atomics_arm.S:88
    175  2 thread 258  __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
    176  1 thread 257  __futex_wait () at system/klibc/android/atomics_arm.S:88
    177 
    178 
    179 (gdb) thread 7
    180 [Switching to thread 7 (thread 263)]#0  __ioctl () at system/klibc/syscalls/__ioctl.S:12
    181 12          movs    r0, r0
    182 (gdb) bt
    183 #0  __ioctl () at system/klibc/syscalls/__ioctl.S:12
    184 #1  0x53010704 in ioctl (fd=-512, request=-1072143871) at system/klibc/android/ioctl.c:22
    185 #2  0x51040ac0 in android::IPCThreadState::talkWithDriver (this=0x1207b8, doReceive=true) at RefBase.h:83
    186 #3  0x510418a0 in android::IPCThreadState::joinThreadPool (this=0x1207b8, isMain=false)
    187    at libs/utils/IPCThreadState.cpp:343
    188 #4  0x51046004 in android::PoolThread::threadLoop (this=0xfffffe00) at libs/utils/ProcessState.cpp:52
    189 #5  0x51036428 in android::Thread::_threadLoop (user=0xfffffe00) at libs/utils/Threads.cpp:1100
    190 #6  0x58025c68 in android::AndroidRuntime::javaThreadShell (args=0x105ffe28) at libs/android_runtime/AndroidRuntime.cpp:540
    191 
    192 (gdb) thread 6
    193 [Switching to thread 6 (thread 262)]#0  accept () at system/klibc/syscalls/accept.S:12
    194 12          movs    r0, r0
    195 (gdb) bt
    196 #0  accept () at system/klibc/syscalls/accept.S:12
    197 #1  0x6b0334e4 in jdwpAcceptConnection (state=0xfffffe00) at extlibs/jamvm-1.4.1/jdwp/JdwpNet.c:213
    198 #2  0x6b032660 in jdwpThreadEntry (self=0x4d020) at extlibs/jamvm-1.4.1/jdwp/JdwpMain.c:37
    199 #3  0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
    200 
    201 (gdb) thread 5
    202 [Switching to thread 5 (thread 261)]#0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    203 88              bx              lr
    204 (gdb) bt
    205 #0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    206 #1  0x53010f48 in pthread_cond_timeout (cond=0x6b039b64, mutex=0x6b039b60, msecs=0) at system/klibc/android/pthread.c:513
    207 #2  0x6b01c8d0 in monitorWait (mon=0x6b039b60, self=0x4d400, ms=1000, ns=272629312) at extlibs/jamvm-1.4.1/src/lock.c:183
    208 #3  0x6b022084 in threadSleep (thread=0x4d400, ms=1000, ns=272629312) at extlibs/jamvm-1.4.1/src/thread.c:215
    209 #4  0x6b00d4fc in asyncGCThreadLoop (self=0x4d400) at extlibs/jamvm-1.4.1/src/alloc.c:1179
    210 #5  0x6b022c2c in shell (args=0x4d480) at extlibs/jamvm-1.4.1/src/thread.c:629
    211 
    212 (gdb) thread 4
    213 [Switching to thread 4 (thread 260)]#0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    214 88              bx              lr
    215 (gdb) bt
    216 #0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    217 #1  0x53010eb8 in pthread_cond_timedwait (cond=0x6b039934, mutex=0x6b039930, abstime=0x0)
    218    at system/klibc/android/pthread.c:490
    219 #2  0x6b00b3ec in referenceHandlerThreadLoop (self=0x4d360) at extlibs/jamvm-1.4.1/src/alloc.c:1247
    220 #3  0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
    221 
    222 (gdb) thread 3
    223 [Switching to thread 3 (thread 259)]#0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    224 88              bx              lr
    225 (gdb) bt
    226 #0  __futex_wait () at system/klibc/android/atomics_arm.S:88
    227 #1  0x53010eb8 in pthread_cond_timedwait (cond=0x6b03992c, mutex=0x6b039928, abstime=0x0)
    228    at system/klibc/android/pthread.c:490
    229 #2  0x6b00b1dc in finalizerThreadLoop (self=0x4d8e0) at extlibs/jamvm-1.4.1/src/alloc.c:1238
    230 #3  0x6b022c2c in shell (args=0x4d960) at extlibs/jamvm-1.4.1/src/thread.c:629
    231 
    232 (gdb) thread 2
    233 [Switching to thread 2 (thread 258)]#0  __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
    234 12          movs    r0, r0
    235 (gdb) bt
    236 #0  __sigsuspend () at system/klibc/syscalls/__sigsuspend.S:12
    237 #1  0x6b023814 in dumpThreadsLoop (self=0x51b98) at extlibs/jamvm-1.4.1/src/thread.c:1107
    238 #2  0x6b022c2c in shell (args=0x51b58) at extlibs/jamvm-1.4.1/src/thread.c:629
    239 </pre>
    240 
    241 <a name="Crash_in_C_C_code"></a><h4>Crash in C / C++ code</h4>
    242 <p>If it crashes, connect with <code>aproto</code> and run <code>logcat</code> on the device. You should see output like this:</p>
    243 
    244 <pre class="prettify">
    245 I/ActivityManager(  188): Starting activity: Intent { component=com.android.calendar.MonthScreen }
    246 I/ActivityManager(  188): Starting application com.android.calendar to host activity com.android.calendar.MonthScree
    247 n
    248 I/ServiceManager(  417): Executing: /android/bin/app_process (link=/android/bin/app_process, wrapper=/android/bin/app_process)
    249 I/DEBUG: -- observer of pid 417 starting --
    250 I/appproc (  417): App process is starting with pid=417, class=android/activity/ActivityThread.
    251 I/DEBUG: -- observer of pid 417 exiting --
    252 I/DEBUG: -- observer of pid 420 starting --
    253 I/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    254 I/DEBUG: pid: 373, tid: 401  &gt;&gt;&gt; android.content.providers.pim &lt;&lt;&lt;
    255 I/DEBUG: signal 11 (SIGSEGV), fault addr 00000000
    256 I/DEBUG:  r0 ffffffff  r1 00000000  r2 00000454  r3 002136d4
    257 I/DEBUG:  r4 002136c0  r5 40804810  r6 0022dc70  r7 00000010
    258 I/DEBUG:  r8 0020a258  r9 00000014  10 6b039074  fp 109ffcf8
    259 I/DEBUG:  ip 6b039e90  sp 109ffc0c  lr 580239f0  pc 6b0156a0
    260 I/DEBUG:          #01  pc 6b0156a0  /android/lib/libjamvm.so
    261 I/DEBUG:          #01  lr 580239f0  /android/lib/libandroid_runtime.so
    262 I/DEBUG:          #02  pc 6b01481c  /android/lib/libjamvm.so
    263 I/DEBUG:          #03  pc 6b0148a4  /android/lib/libjamvm.so
    264 I/DEBUG:          #04  pc 6b00ebc0  /android/lib/libjamvm.so
    265 I/DEBUG:          #05  pc 6b02166c  /android/lib/libjamvm.so
    266 I/DEBUG:          #06  pc 6b01657c  /android/lib/libjamvm.so
    267 I/DEBUG:          #07  pc 6b01481c  /android/lib/libjamvm.so
    268 I/DEBUG:          #08  pc 6b0148a4  /android/lib/libjamvm.so
    269 I/DEBUG:          #09  pc 6b0235c0  /android/lib/libjamvm.so
    270 I/DEBUG:          #10  pc 5300fac4  /android/lib/libc.so
    271 I/DEBUG:          #11  pc 5300fc5c  /android/lib/libc.so
    272 I/DEBUG: -- observer of pid 373 exiting --
    273 I/DEBUG: -- observer of pid 423 starting --
    274 </pre>
    275 
    276 <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>
    277 
    278 <pre class="prettify"> 
    279 pid: 373, tid: 401  &gt;&gt;&gt; android.content.providers.pim &lt;&lt;&lt;
    280 
    281  signal 11 (SIGSEGV), fault addr 00000000
    282   r0 ffffffff  r1 00000000  r2 00000454  r3 002136d4
    283   r4 002136c0  r5 40804810  r6 0022dc70  r7 00000010
    284   r8 0020a258  r9 00000014  10 6b039074  fp 109ffcf8
    285   r8 0020a258  r9 00000014  10 6b039074  fp 109ffcf8
    286 
    287   ADDR      FUNCTION                        FILE:LINE
    288   6b0156a0  executeJava                     extlibs/jamvm-1.4.1/src/interp.c:2674
    289   580239f0  android_util_Parcel_freeBuffer  libs/android_runtime/android_util_Binder.cpp:765
    290   6b01481c  executeMethodVaList             extlibs/jamvm- 1.4.1/src/execute.c:91
    291   6b0148a4  executeMethodArgs               extlibs/jamvm-1.4.1/src/execute.c:67
    292   6b00ebc0  initClass                       extlibs/jamvm-1.4.1/src/class.c:1124
    293   6b02166c  resolveMethod                   extlibs/jamvm- 1.4.1/src/resolve.c:197
    294   6b01657c  executeJava                     extlibs/jamvm-1.4.1/src/interp.c:2237
    295   6b01481c  executeMethodVaList             extlibs/jamvm-1.4.1/src/execute.c:91
    296   6b0148a4  executeMethodArgs               extlibs/jamvm- 1.4.1/src/execute.c:67
    297   6b0235c0  threadStart                     extlibs/jamvm-1.4.1/src/thread.c:355
    298   5300fac4  __thread_entry                  system/klibc/android/pthread.c:59
    299   5300fc5c  pthread_create                  system/klibc/android/pthread.c:182
    300 </pre>
    301 
    302 <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.
    303 </p>
    304 </body>
    305 </html>
    306