Thursday, October 6, 2011

Android/AnalyzingCrashDumps


Android produces a crash dump in the system log. This can be used to get at least an idea of where something crashed. Here's what a crash dump looks like:
I/DEBUG   (20696): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (20696): Build fingerprint: 'Samsung/SGH-I897/SGH-I897/SGH-I897:2.2/FROYO/UCJI6:user/release-keys'
I/DEBUG   (20696): pid: 21148, tid: 21148  >>> /data/data/org.mozilla.fennec/plugin-container <<<
I/DEBUG   (20696): signal 11 (SIGSEGV), fault addr 00000000
I/DEBUG   (20696):  r0 00003860  r1 831175de  r2 00008a6c  r3 831174f1
I/DEBUG   (20696):  r4 835366ac  r5 00000000  r6 411020c8  r7 00000000
I/DEBUG   (20696):  r8 00000000  r9 00000000  10 00000000  fp 00000000
I/DEBUG   (20696):  ip 83536bc0  sp be8bdeb8  lr 82bb380f  pc 82bb3932  cpsr a0000030
I/DEBUG   (20696):  d0  6472656767756265  d1  00000002000400ff
I/DEBUG   (20696):  d2  ffffffff000000ff  d3  00000000ffffffff
I/DEBUG   (20696):  d4  636974617473206d  d5  74642f726f746320
I/DEBUG   (20696):  d6  656c6966203a726f  d7  2e2f2e2e2f2e2e20
I/DEBUG   (20696):  d8  0000000000000000  d9  0000000000000000
I/DEBUG   (20696):  d10 0000000000000000  d11 0000000000000000
I/DEBUG   (20696):  d12 0000000000000000  d13 0000000000000000
I/DEBUG   (20696):  d14 0000000000000000  d15 0000000000000000
I/DEBUG   (20696):  d16 0000000000000000  d17 0000000000000000
I/DEBUG   (20696):  d18 0000000000000000  d19 0000000000000000
I/DEBUG   (20696):  d20 0000000000000000  d21 0000000000000000
I/DEBUG   (20696):  d22 0000000000000000  d23 0000000000000000
I/DEBUG   (20696):  d24 0000000000000000  d25 0000000000000000
I/DEBUG   (20696):  d26 0000000000000000  d27 0000000000000000
I/DEBUG   (20696):  d28 0000000000000000  d29 0000000000000000
I/DEBUG   (20696):  d30 0000000000000000  d31 0000000000000000
I/DEBUG   (20696):  scr 00000000
I/DEBUG   (20696):
I/DEBUG   (20696):          #00  pc 00bb3932  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):          #01  lr 82bb380f  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):
I/DEBUG   (20696): code around pc:
I/DEBUG   (20696): 82bb3910 601a3201 3514ae0a 000cf106 fb90f140
I/DEBUG   (20696): 82bb3920 f1404630 a813fb8d fb8af140 f140a816
I/DEBUG   (20696): 82bb3930 6829fb87 2900af19 af73f47f 46399806
I/DEBUG   (20696): 82bb3940 fcc8f0a5 26249c19 5b08f854 4605fb06
I/DEBUG   (20696): 82bb3950 f104e007 f140000c 4620fb73 fb70f140
I/DEBUG   (20696):
I/DEBUG   (20696): code around lr:
I/DEBUG   (20696): 82bb37ec 50e54628 fc44f0a0 49694b68 58e32204
I/DEBUG   (20696): 82bb37fc 90061861 f840a81a f1333d04 f65efdaf
I/DEBUG   (20696): 82bb380c 4b64cd08 930718e3 18e34b63 46059308
I/DEBUG   (20696): 82bb381c 90054862 aa16e087 46109203 f667ae0a
I/DEBUG   (20696): 82bb382c f10dd82d 46600c4c f8cd6869 f667c010
I/DEBUG   (20696):
I/DEBUG   (20696): stack:
I/DEBUG   (20696):     be8bde78  835366ac  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bde7c  82ce737f  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bde80  00040011
I/DEBUG   (20696):     be8bde84  00000018
I/DEBUG   (20696):     be8bde88  00000000
I/DEBUG   (20696):     be8bde8c  41113500
I/DEBUG   (20696):     be8bde90  835366ac  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bde94  411020c8
I/DEBUG   (20696):     be8bde98  be8bdf1c  [stack]
I/DEBUG   (20696):     be8bde9c  00000004
I/DEBUG   (20696):     be8bdea0  41115188
I/DEBUG   (20696):     be8bdea4  835366ac  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdea8  41115188
I/DEBUG   (20696):     be8bdeac  411020c8
I/DEBUG   (20696):     be8bdeb0  df002777
I/DEBUG   (20696):     be8bdeb4  e3a070ad
I/DEBUG   (20696): #00 be8bdeb8  000000c1
I/DEBUG   (20696):     be8bdebc  00000304
I/DEBUG   (20696):     be8bdec0  00000002
I/DEBUG   (20696):     be8bdec4  00000000
I/DEBUG   (20696):     be8bdec8  00000001
I/DEBUG   (20696):     be8bdecc  00003860
I/DEBUG   (20696):     be8bded0  41113500
I/DEBUG   (20696):     be8bded4  831174e0  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bded8  831174f1  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdedc  8020d7ad  /data/data/org.mozilla.fennec/cache/libnspr4.so
I/DEBUG   (20696):     be8bdee0  00000001
I/DEBUG   (20696):     be8bdee4  835366ac  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdee8  831175de  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdeec  8020d7ad  /data/data/org.mozilla.fennec/cache/libnspr4.so
I/DEBUG   (20696):     be8bdef0  835366ac  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdef4  82ce69ef  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):     be8bdef8  41115324
I/DEBUG   (20696):     be8bdefc  831175de  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696): dumpmesg > /data/log/dumpstate_app_native.log
There's lots of data here, but to start with, the PC (program counter) and LR (return address) are the most useful. LR might not be valid; you'll have to see if it makes sense, but it generally is on ARM since there's plenty of registers to go around.
Even though these two addresses appear in the register list, scrolling down to this section:
I/DEBUG   (20696):          #00  pc 00bb3932  /data/data/org.mozilla.fennec/cache/libxul.so
I/DEBUG   (20696):          #01  lr 82bb380f  /data/data/org.mozilla.fennec/cache/libxul.so
gives you some more information. PC was listed as 82bb3932 originally, but is 00bb3932 here. The dumper helpfully stripped the base relocation address of the library, which is handy.
On your desktop, you can now do something like:
% arm-eabi-objdump -d -l --start-address=0x00bb3920 --stop-address=0x00bb3950 bin/libxul.so \
   | arm-eabi-c++filt
bin/libxul.so:     file format elf32-littlearm

Disassembly of section .text:

00bb3920 <mozilla::dom::ContentChild::Init(MessageLoop*, int, IPC::Channel*)+0x1a0>:
~nsACString_internal():
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../dist/include/nsTSubstring.h:113
  bb3920:       000c            lsls    r4, r1, #0
  bb3922:       f140 fb91       bl      cf4048 <nsACString_internal::Finalize()>
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../../mozilla-central/dom/ipc/ContentChild.cpp:256
  bb3926:       4630            mov     r0, r6
  bb3928:       f140 fb8e       bl      cf4048 <nsACString_internal::Finalize()>
  bb392c:       a813            add     r0, sp, #76
  bb392e:       f140 fb8b       bl      cf4048 <nsACString_internal::Finalize()>
  bb3932:       a816            add     r0, sp, #88
  bb3934:       f140 fb88       bl      cf4048 <nsACString_internal::Finalize()>
mozilla::dom::ContentChild::Init(MessageLoop*, int, IPC::Channel*)():
  bb3938:       6829            ldr     r1, [r5, #0]
  bb393a:       af19            add     r7, sp, #100
  bb393c:       2900            cmp     r1, #0
  bb393e:       f47f af73       bne.w   bb3828 <mozilla::dom::ContentChild::Init(MessageLoop*, int, IPC::Channel*)+0xa8>
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../../mozilla-central/dom/ipc/ContentChild.cpp:264
  bb3942:       9805            ldr     r0, [sp, #20]
  bb3944:       4639            mov     r1, r7
  bb3946:       f0a5 fcc9       bl      c592dc <mozilla::dom::PCrashReporterChild::SendAddLibraryMappings(InfallibleTArray<mozilla::dom::Mapping> const&)>
nsTArray_base<nsTArrayInfallibleAllocator>::Length() const():
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../dist/include/nsTArray.h:139
  bb394a:       9c19            ldr     r4, [sp, #100]
nsTArray<mozilla::dom::Mapping, nsTArrayInfallibleAllocator>::DestructRange(unsigned int, unsigned int)():
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../dist/include/nsTArray.h:1104
  bb394c:       2624            movs    r6, #36
nsTArray_base<nsTArrayInfallibleAllocator>::Length() const():
/cygdrive/c/proj/m2/fennec-android/dom/ipc/../../dist/include/nsTArray.h:139
  bb394e:       f854 5b08       ldr.w   r5, [r4], #8

(using the tools in the SDK prebuilt tools dir, though any android toolchain should really work).
You can repeat the same process for the LR value, though you'll have to strip the library location (in this case, 0x82000000) manually; same for any of the other stack addresses.
A brief note about ARM addresses: ARM instructions can be either normal/ARM (4-byte) or Thumb (2-byte). The above example uses Thumb instructions, and objdump recognizes them as such. You may see a lr value that has the high bit set -- this indicates that the return is supposed to take place to the Thumb instruction set. Simply strip off that bit to get the actual address -- for example, 0x....f would become 0x....e and 0x....1 would become 0x....0. If you don't, objdump will happily decode nonsensical instructions from the unaligned addresses.

No comments:

Post a Comment