1.启动gdb

gdb可以使用我们源码prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin路径下的arm-eabi-gdb即可,方法是:

  在源码根目录下执行:

1) source build/envsetup.sh

2)lunch 对应版本

3)arm-eabi-gdb

2.查看core文件发现出错位置

进入gdb后,默认终端下会有gdb标识,然后执行如下命令

1)使用file命令,关联出问题进程的可执行程序,可执行程序的路径在/symbols/system/bin/下,一般是app_process

(gdb) file./symbols/system/bin/app_process

  2)使用set命令,设置默认lib的搜索路径

(gdb) set solib-search-pathsymbols/system/lib/

3.利用core命令 打开响应的coredump文件,coredump文件目前平台统一生成到了mnt/sdcard/slog/corefile下面,命名格式是core-出问题应用进程名字-pid

(gdb) core./core-com.android.mms-19934

如下是执行完core后的显示结果

GDB will be unable to debugshared library initializers

and track explicitly loadeddynamic code.

Core was generated by`com.android.email                                                         '.

Program terminated withsignal 11, Segmentation fault.

#0  scanObject(obj=0x40e17b68, ctx=0xa5d750) at dalvik/vm/alloc/MarkSweep.cpp:460

warning: Source file is morerecent than executable.

460     }else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {

2.利用 gdb命令 进行调试 ,常用的gdb命令可以百度一下,

如下实例显示如何使用及结果

1)查看调用堆栈信息,命令:bt

(gdb) bt

#0  scanObject (obj=0x40e17b68,ctx=0xa5d750) at dalvik/vm/alloc/MarkSweep.cpp:460

#1  0x40858d60 inprocessMarkStack (ctx=0xa5d750) at dalvik/vm/alloc/MarkSweep.cpp:479

#2  0x40848ef8 indvmCollectGarbageInternal (spec=0x408db01c) at dalvik/vm/alloc/Heap.cpp:530

#3  0x40849510 intryMalloc (size=1048592, flags=0) at dalvik/vm/alloc/Heap.cpp:228

#4  dvmMalloc(size=1048592, flags=0) at dalvik/vm/alloc/Heap.cpp:357

#5  0x4088a378 inallocArray (arrayClass=0x40b277d8, length=1048576, elemWidth=<valueoptimized out>, allocFlags=1085432296)

    atdalvik/vm/oo/Array.cpp:58

#6  0x4088a484 indvmAllocPrimitiveArray (type=<value optimized out>, length=10868560,allocFlags=0) at dalvik/vm/oo/Array.cpp:158

#7  0x4086a4d0 inNewByteArray (env=<value optimized out>, length=1048576) atdalvik/vm/Jni.cpp:2373

#8  0x401f273a in_JNIEnv::NewByteArray (env=0xa5d500, bitmap=0xbeaa54b4, ctable=0x0) atdalvik/libnativehelper/include/nativehelper/jni.h:883

#9 GraphicsJNI::allocateJavaPixelRef (env=0xa5d500, bitmap=0xbeaa54b4, ctable=0x0)

    atframeworks/base/core/jni/android/graphics/Graphics.cpp:491

#10 0x401f2782 inJavaPixelAllocator::allocPixelRef (this=0xbeaa552c, bitmap=0xbeaa54b4,ctable=0x0)

    atframeworks/base/core/jni/android/graphics/Graphics.cpp:527

#11 0x4066eb24 in SkBitmap::allocPixels(this=0xbeaa54b4, allocator=0x2f1b, ctable=0x0) atexternal/skia/src/core/SkBitmap.cpp:367

#12 0x40663db8 inSkPNGImageDecoder::onDecode (this=<value optimized out>,sk_stream=<value optimized out>,

   decodedBitmap=<value optimized out>, mode=<value optimized out>) atexternal/skia/src/images/SkImageDecoder_libpng.cpp:328

2)查看出问题时的汇编代码.命令 disass

Dump of assembler code forfunction scanObject:

   0x40858b40<+0>:     push       {r4, r5, r6, r7, r8, lr}

   0x40858b44<+4>:      mov r4, r0

   0x40858b48<+8>:      ldr   r0, [pc,#480]       ; 0x40858d30 <scanObject+496>

   0x40858b4c<+12>:    mov r7, r1

   0x40858b50<+16>:    ldr   r5, [pc, r0]

   0x40858b54<+20>:    ldr   r0, [r4]  //从r4地址处读出,保存到r0

   0x40858b58<+24>:    ldr   r3, [r5,#176]       ; 0xb0

   0x40858b5c<+28>:    cmp r0, r3

   0x40858b60<+32>:    beq 0x40858c50 <scanObject+272>

=> 0x40858b64<+36>:    ldr   r12, [r0,#32]                    <<<====出错位置

   0x40858b68<+40>:    tst    r12,#1073741824      ; 0x40000000

   0x40858b6c<+44>:    beq 0x40858bb8 <scanObject+120>

   0x40858b70<+48>:    bl    0x4085865c<markObject>

   0x40858b74<+52>:    ldr   r0, [r4]

   0x40858b78<+56>:    ldr   r3, [r0, #32]

   0x40858b7c<+60>:    tst    r3, #536870912  ; 0x20000000

   0x40858b80<+64>:    popeq    {r4, r5, r6, r7, r8, pc}

   0x40858b84<+68>:    ldr   lr, [r4, #8]

   0x40858b88<+72>:    add r6, r4, #16

3).查看对应寄存器的值,命令info reg:

(gdb) info reg

r0            0x450053    4522067

r1            0xa5d750    10868560

r2            0x100044    1048644

r3            0x40b261e8       1085432296

r4            0x40e17b68       1088519016

r5            0x408e5088       1083068552

r6            0x408e03a0 1083048864

r7            0xa5d750    10868560

r8            0x0       0

r9            0x0       0

r10           0x317bd3    3242963

r11           0x408e5088 1083068552

r12           0x2f1b  12059

sp            0xbeaa5270 0xbeaa5270

lr            0x40858d60 1082494304

查看当时寄存器的信息及参数变量对应的值,发现obj->clazz与r0寄存器中的值是一样的,然后寻找对应函数的源码为dalvik/vm/alloc/MarkSweep.cpp

static void scanObject(constObject *obj, GcMarkContext *ctx)

{

   assert(obj != NULL);

   assert(obj->clazz != NULL);

    if(obj->clazz == gDvm.classJavaLangClass) {

       scanClassObject(obj, ctx);

    } else if(IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {   <<<===出错位置

       scanArrayObject(obj, ctx);

    } else {

       scanDataObject(obj, ctx);

    }

}

5)可以利用p命令查看变量及函数的值或者地址

6)利用x命令查看某一内存地址附近的信息

在遍历对象的时候某一object的clazz(看源代码该变量表示classobject的一个指针)不对,查看该值附近的内存信息,有内存覆盖的现象

7)当然很重要的一点要看出问题的时候对应的应用进程和线程都进行了哪些操作,这点可以从main&system log中查看

 

Logo

更多推荐