Native调试方法, 一个tombstome文件如下 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'sprd/sprdroid_base/hsdroid:2.3.5/MocorDroid2.3.5/W13.08_20130218.033702:eng/test-keys' pid: 151, tid: 23358 >>> /system/bin/mediaserver <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 80c1e0c8 r0 00086b34 r1 68000010 r2 00000000 r3 80c1e0bc r4 00000000 r5 00000000 r6 0005adc8 r7 00066830 r8 80b09015 r9 00083c38 10 00008000 fp 00000001 ip a39ad7ec sp 41627e60 lr a3928d5d pc a3928d64 cpsr 40800030 d0 6f6365443a3a4f41 d1 614d687469576564 d2 6e45692072656b72 d3 6165727453666f64 d4 9f9f9f9f9f9f9f9f d5 a1a1a1a1a1a1a1a1 d6 a2a2a2a2a2a2a2a2 d7 a2a2a2a2a2a2a2a2 d8 7979797979797979 d9 7979797979797979 d10 0101010101010101 d11 0000000000000000 d12 01e701e701e701e7 d13 01e701e701e701e7 d14 7878787878787878 d15 7979797979797979 d16 000000000019e100 d17 a5a5a5a5a5a5a5a5 d18 a5a5a5a5a5a5a5a5 d19 a5a5a5a5a5a5a5a5 d20 a5a5a5a5a5a5a5a5 d21 a4a4a4a4a4a4a4a4 d22 a4a4a4a4a4a4a4a4 d23 a2a2a2a2a2a2a2a2 d24 016d016d016d016d d25 016d016d016d016d d26 7a7a7a7a7a7a7a7a d27 7a7a7a7a7a7a7a7a d28 00f200f200f200f2 d29 00f200f200f200f2 d30 00f400f400f400f4 d31 00f400f400f400f4 scr 68000010 #00 pc 00028d64 /system/lib/libopencore_common.so #01 pc 00028f8c /system/lib/libopencore_common.so #02 pc 000292f0 /system/lib/libopencore_common.so #03 pc 00008f66 /system/lib/libomx_sharedlibrary.so #04 pc 00009064 /system/lib/libomx_sharedlibrary.so #05 pc 00011d4c /system/lib/libc.so #06 pc 00011910 /system/lib/libc.so code around pc: a3928d44 e0594788 68319e06 5ca0f501 4000f8dc a3928d54 2004eb01 e9daf7f8 b9204604 68039804 a3928d64 479068da f1b0e005 bf063fff 684c9906 a3928d74 98062400 ffa8f00b d03d2c00 68089904 a3928d84 46086883 47984621 28004604 9d05d034 code around lr: a3928d3c 46289d04 68d9682b e0594788 68319e06 a3928d4c 5ca0f501 4000f8dc 2004eb01 e9daf7f8 a3928d5c b9204604 68039804 479068da f1b0e005 a3928d6c bf063fff 684c9906 98062400 ffa8f00b a3928d7c d03d2c00 68089904 46086883 47984621 stack: 41627e20 0005a808 41627e24 0000000a 41627e28 80b084d9 /system/lib/libomx_sharedlibrary.so 41627e2c 00000001 41627e30 00066890 41627e34 00066894 41627e38 00066898 41627e3c 00000000 41627e40 00000003 41627e44 00066830 41627e48 00000000 41627e4c 00000000 41627e50 0005adc8 41627e54 afd0d00c /system/lib/libc.so 41627e58 df002777 41627e5c e3a070ad #00 41627e60 00066844 41627e64 a392a451 /system/lib/libopencore_common.so 41627e68 00000000 41627e6c 000667e8 41627e70 00086b34 41627e74 000667e8 41627e78 0005adc8 41627e7c a39ad7b0 41627e80 000667e8 41627e84 00000000 41627e88 00000001 41627e8c a3928f91 /system/lib/libopencore_common.so #01 41627e90 00000000 41627e94 80b09015 /system/lib/libomx_sharedlibrary.so 41627e98 00083c38 41627e9c 00000078 41627ea0 80b09015 /system/lib/libomx_sharedlibrary.so 41627ea4 a39292f5 /system/lib/libopencore_common.so #02 41627ea8 0005adc8 41627eac 000667e8 41627eb0 00000000 41627eb4 80b08f69 /system/lib/libomx_sharedlibrary.so #03 41627eb8 41627f00 41627ebc 00083c38 41627ec0 41627f00 41627ec4 0005adc8 41627ec8 0005adc8 41627ecc 00083c3c 41627ed0 00000000 41627ed4 00000000 41627ed8 41627f00 41627edc 80b09069 /system/lib/libomx_sharedlibrary.so #04 41627ee0 00083c38 41627ee4 0005adc8 41627ee8 00000000 41627eec afd11d50 /system/lib/libc.so #05 41627ef0 41627f00 41627ef4 0005ad50 41627ef8 418a0c08 41627efc afd11914 /system/lib/libc.so #06 41627f00 41627f00 41627f04 0005ad50 41627f08 00000002 41627f0c 00000000 41627f10 00000000 41627f14 00000000 41627f18 0005ad90 41627f1c 00000000 41627f20 00000000 41627f24 00000000 41627f28 00000000 41627f2c 00000000 41627f30 00000000 41627f34 00000000 41627f38 00000000 41627f3c 00000000 41627f40 00000000 41627f44 00000000 这个可以使用stacktrace工具来查看 ./stacktrace --symbols-dir=符号表目录 tombstome_file 另外还可以用core dump进行调试 core dump需要一下几个步骤,对android,可以在开机的时候在init.rc里去执行 在init.rc里加上 setrlimit 4 -1 -1 write /proc/sys/kernel/core_pattern "/local/log/core-%e-%p-%t" (1)使用ulimit命令开启coredump功能。 (2)修改coredump文件生成位置与名称 (3)gdb的使用方法 【3】实践 (1)adb连接手机,开启coredump # ulimit -a ulimit -a time(seconds) unlimited file(blocks) unlimited data(kbytes) unlimited stack(kbytes) 8192 coredump(blocks) unlimited //这里coredump是开启的,大小为不限制,可以用ulimit -c unlimited修改成不限制大小 memory(kbytes) unlimited locked memory(kbytes) 64 process(processes) 4096 nofiles(descriptors) 1024 (2)配置coredump文件生成位置与名称 #echo "1" > /proc/sys/kernel/core_uses_pid //允许文件名后加pid #echo "/local/log/core-%e-%p" > /proc/sys/kernel/core_pattern #echo 1 > /proc/sys/fs/suid_dumpable 把dump文件存放目录改到local/log下。 (3)示例程序 foo.c #include <stdio.h> static void sub(void); int main(void) { sub(); return 0; } static void sub(void) { int *p = NULL; printf("%d",*p); } 然后编译,android会生成两种版本的文件,一种是带符号信息的, out/target/product/generic/symbols/system/bin/foo 另一种是不带符号信息的(即strip过的) out/target/product/generic/system/bin/foo 不带符号信息的会做到system.img中去,带符号信息的我们需要保存住,以备后续调试用。 上面第二个log信息就是此程序运行的结果。 (4)运行 我们把generic/system/bin/foo文件拷贝到手机中,比如local目录下,修改权限(chmod 777 foo),执行,结果如下。 #./foo [1] + Stopped (signal) ./foo # [1] Segmentation fault (core dumped) ./foo # 然后可以看到/local/log目录下多了一个coredump文件, 进程id位1673 core-foo-1673 拿gdb调试 将core-foo-1673与generic/symbols/system/bin/foo(这个必须是带符号的)拷贝到相同目录下 运行gdb进行调试,注意这里要运行的gdb是android自带的,我这里的名称叫arm-eabi-gdb $arm-eabi-gdb ./foo GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. The GDB was configured as "--host=i686-unknown-linux-gnu --target=arm-elf-linux"... (gdb) 输入core-file文件,回车 (gdb) core-file core-foo-1672 warning: core file may not match specified executable file. Error while mapping shared library sections: /system/bin/linker: No such file or directory. Error while mapping shared library sections: libc.so: Success. Error while mapping shared library sections: libstdc++.so: Success. Error while mapping shared library sections: libm.so: Success. Symbol file not found for /system/bin/linker Symbol file not found for libc.so Symbol file not found for libstdc++.so Symbol file not found for libm.so warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. Core was generated by `./foo'. Program terminated with signal 11, Segmentation fault. #0 0x0000836a in main () at external/coredump/foo.c:15 ==》看到这种信息知道该知道哪出错了把 15 printf("%d",*p) (gdb) 如果函数调用关系比较复杂,可试试bt(backtrace)指令 附录:在PC机上做的实验 linux 上core dump及应用 【1】core dump 概念 http://en.wikipedia.org.nyud.net:8080/wiki/Core_dump 【2】示例:在Linux下产生并调试core文件 参考http://www.zedware.org/code/code-coredump.html $ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) 4 max memory size (kbytes, -m) unlimited open files (-n) 2048 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited 写个简单的程序,看看core文件是不是会被产生。创建foo.c,使内容如下。 $ more foo.c #include <stdio.h> static void sub(void); int main(void) { sub(); return 0; } static void sub(void) { int *p = NULL; /* derefernce a null pointer, expect core dump. */ printf("%d", *p); } $ gcc -Wall -g foo.c 【-Wall :[Warning all] 显示所有常用的编译警告信息。 -g选项,将调试信息加入到目标文件或可执行文件中。】 $ ./a.out Segmentation fault 【所谓的Segmentation Fault(段错误)就是指访问的内存超出了系统所给这个程序的内存空间】 $ ls -l core* ls: core*: No such file or directory 没有找到core文件,我们改改ulimit的设置,让它产生,1024是随便取的,也可以使用ulimit -c unlimited不限制大小。 $ ulimit -c 1024 $ ulimit -a core file size (blocks, -c) 1024 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) 4 max memory size (kbytes, -m) unlimited open files (-n) 2048 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited $ ./a.out Segmentation fault (core dumped) $ ls -l core* -rw------- 1 uniware uniware 53248 Jun 30 17:10 core.9128 【此处也可能是名称为core的文件】 注意看上述的输出信息,多了个(core dumped)。确实产生了一个core文件,9128是该进程的PID。我们用GDB来看看这个core。 $ gdb --core=core.9128 GNU gdb Asianux (6.0post-0.20040223.17.1AX) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This was configured as "i386-asianux-linux-gnu". Core was generated by `./a.out'. Program terminated with signal 11, Segmentation fault. #0 0x08048373 in ?? () (gdb) bt #0 0x08048373 in ?? () #1 0xbfffd8f8 in ?? () #2 0x0804839e in ?? () #3 0xb74cc6b3 in ?? () #4 0x00000000 in ?? () 此时用bt看不到backtrace,也就是调用堆栈,原来GDB还不知道符号信息在哪里。我们告诉它一下: (gdb) file ./a.out Reading symbols from ./a.out...done. Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) bt #0 0x08048373 in sub () at foo.c:17 #1 0x08048359 in main () at foo.c:8 此时backtrace出来了。 (gdb) l (此处是“L”的小写,不是数字“1”) 8 sub(); 9 return 0; 10 } 11 12 static void sub(void) 13 { 14 int *p = NULL; 15 16 /* derefernce a null pointer, expect core dump. */ 17 printf("%d", *p); (gdb) 【3】总结 参考http://blog.csdn.net/shaovey/archive/2008/07/31/2744487.aspx 在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。 1.core文件的生成开关和大小限制 1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。 2)使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此core文件的时候,gdb会提示错误。若ulimit -c unlimited,则表示core文件的大小不受限制。ulimit -c 0关闭该功能。 PS: ulimit使用方法见http://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/ 2.core文件的名称和生成路径 core文件生成路径:输入可执行文件运行命令的同一路径下。 若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的core文件。 1)/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1,表示添加pid作为扩展名,生成的core文件格式为core.xxxx;为0则表示生成的core文件同一命名为core。 可通过以下命令修改此文件: echo "1" > /proc/sys/kernel/core_uses_pid 2)proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。 可通过以下命令修改此文件: echo "/corefile/core-%e-%p-%t" > core_pattern,可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳 以下是参数列表: %p - insert pid into filename 添加pid %u - insert current uid into filename 添加当前uid %g - insert current gid into filename 添加当前gid %s - insert signal that caused the coredump into the filename 添加导致产生core的信号 %t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间 %h - insert hostname where the coredump happened into filename 添加主机名 %e - insert coredumping executable name into filename 添加命令名 3.core文件的查看 core文件需要使用gdb来查看。 gdb ./a.out core-file core.xxxx 使用bt命令即可看到程序出错的地方。 以下两种命令方式具有相同的效果,但是在有些环境下不生效,所以推荐使用上面的命令。 1)gdb -core=core.xxxx file ./a.out bt 2)gdb -c core.xxxx file ./a.out bt