Get it free, Try now

Free Cell Phones

Monday, September 27, 2010

How to Analyse Stack trace on Android

This article involves on how to Analyze stack trace on ANDROID, although there are tools available on how to make analysis on stack trace but I personally followed the below procedure.

1. Take a object dump of the the library(.so) using provided android tools

C:\android-ndk-r4b\build\prebuilt\windows\arm-eabi-4.2.1\bin>arm-eabi-objdump -S C:\andy\workspace\aolqaOEM\obj\local\armeabi-v7a\libaolqaWrapperDll.s
o > aolqalib.asm


C:\android-ndk-r4b\build\prebuilt\windows\arm-eabi-4.2.1\bin>arm-eabi-objdump -dR C:\andy\workspace\aolqaOEM\obj\local\armeabi-v7a\libaolqaWrapperDll.s
o > aolqalib.asm

aolqalib.asm is now disassembled, which mean you are now able to trace address assigned to each function in the library.

2. Copy aside the stack trace from the log-cat view of carbide.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/passion/passion/mahimahi:2.2/FRF91/43546:user/release-keys'
pid: 864, tid: 872 >>> xyz <<<
signal 11 (SIGSEGV), fault addr 002b3000
r0 47c23f10 r1 002b2fe8 r2 000b9e01 r3 00000008
r4 47ba9008 r5 00134d49 r6 002380c0 r7 80a4b724
r8 00000001 r9 474ea970 10 00291bf8 fp 0013f200
ip 00000000 sp 474ea320 lr afd1d56d pc afd0f1bc cpsr 20000010
d0 643a64696f72646e d1 6472656767756265
d2 0000002800000000 d3 0000000000000000
d4 0000000000000000 d5 0000000000000000
d6 0000000000000000 d7 0000000000000000
d8 46fdf80042e00000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 8000000000000000 d17 7e37e43c8800759c
d18 4085600000000000 d19 bfad7afccc419668
d20 4000000000000000 d21 3f114affd5703473
d22 bebbaaebd181c43f d23 3fd48e703a724000
d24 3e66376972bea4d0 d25 bff0000000000000
d26 3ff1687200000000 d27 bfad7afccc419669
d28 bffb22b279caa806 d29 3fd48e70431efbb1
d30 3c591e88027bf155 d31 3e41597762000000
scr 20000012
#00 pc 0000f1bc /system/lib/
#01 pc 0001d56a /system/lib/
#02 pc 0000fccc /data/data/xyz/lib/
code around pc:
afd0f19c f5d1f000 f5d1f040 e2522040 3a000009
afd0f1ac f5d1f080 f5d1f0c0 f5d1f100 f421020d
afd0f1bc f421420d f5d1f100 e2522040 f400022d
afd0f1cc f400422d 2afffff8 e2822040 e2522020
afd0f1dc 3a000003 f421020d e2522020 f400022d
code around lr:
afd1d54c bf00e7ee 4606b570 ef5cf7f1 46281c45
afd1d55c fbdcf7ef b1184604 462a4631 edeaf7f1
afd1d56c bd704620 bf004b06 b510a200 189b4c05
afd1d57c 7280f44f 4621191c f840f000 bd104620
afd1d58c 00024db0 000022ac b5f02800 b085460c
474ea2e0 00000001
474ea2e4 474ea970
474ea2e8 00291bf8 [heap]
474ea2ec afd0c6c7 /system/lib/
474ea2f0 80a45141 /data/data/xyz/lib/
474ea2f4 474ea844
474ea2f8 00000011
474ea2fc 00000032
474ea300 80a4b724 /data/data/xyz/lib/
474ea304 afd0cd31 /system/lib/
474ea308 474ea844
474ea30c 80a4b7a8 /data/data/xyz/lib/
474ea310 00134d49 [heap]
474ea314 002380c0 [heap]
474ea318 df002777
474ea31c e3a070ad
#00 474ea320 47ba9008
474ea324 afd1d56d /system/lib/
#01 474ea328 80bb8250 /data/data/xyz/lib/
474ea32c 80a405d9 /data/data/xyz/lib/
474ea330 002380c0 [heap]
474ea334 80a0fcd1 /data/data/xyz/lib/

3. Now look at the last function call from user defined library in ourcase its, the program counter (pc) value is 0000fccc, which triggers the next function call in @pc value 0001d56a and which in turn call another function @pc value 0000f1bc in

Open the disassembled file and try to find the first PC value i,e 0000fccc exclude zeros before find only 'fccc' without inverted commas will fetch you something like this
fcc2: 980f ldr r0, [sp, #60]
fcc4: f8cd 3510 str.w r3, [sp, #1296]
fcc8: f8cd 3514 str.w r3, [sp, #1300]
fccc: f7fd fc64 bl d598
fcd0: f8dd 353c ldr.w r3, [sp, #1340]
fcd4: f50d 6ca6 add.w ip, sp, #1328 ; 0x530

if you scroll upwards you will find function call starting from 0000f8d0 which is the address assigned to function in library,so the function 0000fccc is called inside this method.
0000f8d0 :
f8d0: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
f8d4: ed2d 8b02 vstmdb sp!, {d8}
f8d8: f5ad 6da8 sub.w sp, sp, #1344 ; 0x540
f8dc: b081 sub sp, #4
f8de: 4cc6 ldr r4, [pc, #792] (fbf8 )
f8e0: af34 add r7, sp, #208

now call on function indicates clearly that the crash was somewhere inside SetToCString method of CNewStdString.

Hope this helps, next session will try to write an article on how to hide function address inside .so file


  1. Use second dump cammand to generate meaning ful symbols i;e with options '-dR'

  2. To hide methods in symbol table add the line below in
    LOCAL_CFLAGS := -fvisibility=hidden

    and add the below statement in front of the function which you want to disable inside JNI wrapper header

    P.S: Not tested code