Android——coredump解析

撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/46916869本文来自 【jscese】的博客!

coredump文件生成

前文Android——coredump 配置 记录了android平台上的环境配置,生成方式 正常即为process触发那几种signal

手动coredump状态:

  1. 连接gdb -gcore pid
  2. 终端发送signal终止process: kill -s signal pid 自然发送能产生coredump的signal ,前文有记录,但是有时一次还杀不掉process signal可以被忽视。
    signal可参考:
root@:/ # kill -l                                                           
 1    HUP Hangup                        33     33 Signal 33               
 2    INT Interrupt                     34     34 Signal 34               
 3   QUIT Quit                          35     35 Signal 35               
 4    ILL Illegal instruction           36     36 Signal 36               
 5   TRAP Trap                          37     37 Signal 37               
 6   ABRT Aborted                       38     38 Signal 38               
 7    BUS Bus error                     39     39 Signal 39               
 8    FPE Floating point exception      40     40 Signal 40               
 9   KILL Killed                        41     41 Signal 41               
10   USR1 User signal 1                 42     42 Signal 42               
11   SEGV Segmentation fault            43     43 Signal 43               
12   USR2 User signal 2                 44     44 Signal 44               
13   PIPE Broken pipe                   45     45 Signal 45               
14   ALRM Alarm clock                   46     46 Signal 46               
15   TERM Terminated                    47     47 Signal 47               
16 STKFLT Stack fault                   48     48 Signal 48               
17   CHLD Child exited                  49     49 Signal 49               
18   CONT Continue                      50     50 Signal 50               
19   STOP Stopped (signal)              51     51 Signal 51               
20   TSTP Stopped                       52     52 Signal 52               
21   TTIN Stopped (tty input)           53     53 Signal 53               
22   TTOU Stopped (tty output)          54     54 Signal 54               
23    URG Urgent I/O condition          55     55 Signal 55               
24   XCPU CPU time limit exceeded       56     56 Signal 56               
25   XFSZ File size limit exceeded      57     57 Signal 57               
26 VTALRM Virtual timer expired         58     58 Signal 58               
27   PROF Profiling timer expired       59     59 Signal 59               
28  WINCH Window size changed           60     60 Signal 60               
29     IO I/O possible                  61     61 Signal 61               
30    PWR Power failure                 62     62 Signal 62               
31    SYS Bad system call               63     63 Signal 63               
32     32 Signal 32                     64     64 Signal 64

gdb调试coredump

以simplejni apk中 jni崩溃 得到的core.droid.simplejni.1797文件拷贝到编译源码的根目录为例

源码目录下使用编译工具链的gdb

也可以cygwin终端下或者eclipse环境下使用ndk的gdb操作,经过多次调试发现有的动态库中的symbol信息, ndk的gdb无法显示完全!

  1. 开启android gdb:
./prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb

2.gdb模式下设置动态库搜索加载路径:

set solib-search-path /home/..../out/target/product/../symbols/system/lib/

设置到源码编译的out目录下的symbol


3.加载启动程序:

file out/target/product/../symbols/system/bin/XXX 
//app进程最后XXX就是app_process32,zygote的启动程序,根据情况修改

4.加载core文件:
加载core文件


5.常用命令:
==============command=========
set logging on/off log保存

backtrace(bt) n 回溯n个调用栈

list n 显示源码 或者显示行数
list - 向上显示

set listsize n 设置打印行数

frame(f) n 切换栈帧
info frame(f) 0 第几栈帧的信息

info args 显示当前栈帧函数参数

info locals 当前帧函数局部变量

info threads / thread n 查看线程信息/切换线程

info (all-)register/ info r rname 查看全部寄存器/根据寄存器名查看

info line filename:func/line 查看文件中某行代码当时在内存中的地址:

info line

disassemble fuc / disassemble $pc 反汇编函数/反汇编pc寄存器指向的指令所属函数:

disassemble


x/fu address 查看内存中的值
f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

pc 的值为下一条指令存放的地址,此时的pc值所指向的指令为:
pc

后面0x2004681b代表的即为汇编的arm指令

此时执行的指令是 ldr r3, [r3, #0]
加载 [r3, #0] 地址的值给 r3寄存器, 可以看到前面还有一句:
movs r3, #0 设成了0
可查看r3 寄存器当前的值,p X:

p-x

这里就是从 0 地址加载,访问了 0地址内存,空指针,导致段错误


记录

surfaceflinger-DDR
报非法指令,反汇编看到pc所指的指令,这里指向的是gdb反汇编了symbol下对应的动态库(libsurfaceflinger.so)再根据内存地址以及在动态库中的偏移得到的,同样可以查看当时内存中的指令:

这里写图片描述

由于报非法指令,我们可以手动去反汇编libsurfaceflinger.so 校验一下实际的与内存中的指令是否一致:
源码目录下:

prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-objdump -S -D out/target/product/../symbols/system/lib/libsurfaceflinger.so > libsurfaceflinger.txt
objdump -x obj 以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出 <可查到该文件的所有动态库>

objdump -t obj 输出目标文件的符号表()

objdump -h obj 输出目标文件的所有段概括()

objdump -j .text/.data -S obj 输出指定段的信息,大概就是反汇编源代码把

objdump -S obj C语言与汇编语言同时显示

查看libsurfaceflinger.txt汇编文件
可根据上面的 info line 得到的地址与这里的地址算偏移,算出libsurfaceflinger.txt中应该对应的指令

或者以没有崩溃前的cat /proc/4702(pid)/maps 查看内存映射,算偏移地址得到指令:

//动态库被加载到内存的映射
root:/ # cat /proc/4702(pid)/maps | grep surface                                
b6ec5000-b6ef4000 r-xp 00000000 5d:10 1567       /system/lib/libsurfaceflinger.so
b6ef4000-b6ef9000 r--p 0002e000 5d:10 1567       /system/lib/libsurfaceflinger.so
b6ef9000-b6efa000 rw-p 00033000 5d:10 1567       /system/lib/libsurfaceflinger.so
b6feb000-b6fed000 r-xp 00000000 5d:10 464        /system/bin/surfaceflinger
b6fed000-b6fee000 r--p 00001000 5d:10 464        /system/bin/surfaceflinger
一共有6列
第一列代表内存段的虚拟地址
第二列代表执行权限,r,w,x不必说,p=私有 s=共享
不用说,heap和stack段不应该有x,否则就容易被xx,不过这个跟具体的版本有关
第三列代表在进程地址里的偏移量
第四列映射文件的主设备号和次设备号
通过 cat /proc/devices
得知fd是253 device-mapper
第五列映像文件的节点号,即inode
第六列是映像文件的路径

这里发现内存中指令是对的,考虑可能是cpu取指出错

//汇编
//寄存器存储
stmia, 比如当前ro指向的内存地址是 0x1000,STMIA RO!,{R1-R7} 就是 首先把r1存入 0x1000,
然后r2存入0x1004,然后r3存入0x1008,如果是32位的处理器就是每次加4个字节,以此类推把 r1-r7按照递增的地址存入。。。。
这个r0!就是从r0的地址开始存的意思。。。

stmia.w r11, {r2, r3, r4, r5} //.w的意思是告诉编译器,这条指令采用32bit编码。
相同:
str.w r2 [r11] //将寄存器r2的值存入r11指向的地址上 ,寄存器本身r11本身的值不变
str.w r3, [r11,#4]
str.w r4, [r11,#8]
str.w r5, [r11,#12]

32bit 一次+4 byte

stmdb 则是地址从r0开始减少,依次存储。。。

暂时记录这么多~ 后续有需要再添加~

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Androidcoredump是指系统或应用程序由于某些错误而崩溃时,生成的一种二进制文件,包含了崩溃时的内存状态和寄存器信息等调试信息。这个文件可以帮助开发人员定位和解决崩溃问题。 在Android中,生成coredump的方式有多种,其中最常用的是通过adb命令行工具获取。具体步骤如下: 1. 连接Android设备到电脑,并打开调试模式。 2. 在电脑上打开命令行工具,输入以下命令: ``` adb shell ``` 3. 进入设备的shell环境后,输入以下命令: ``` su ``` 4. 获取正在运行的应用程序的PID号,例如: ``` ps | grep com.example.app ``` 5. 使用gdbserver启动应用程序,并将coredump写入指定文件中,例如: ``` gdbserver :5039 --attach <PID> --core <filename> ``` 其中,`:5039`是gdbserver监听的端口号,`<PID>`是应用程序的进程ID,`<filename>`是coredump文件的保存路径和文件名。 6. 在另一个终端窗口中,打开gdb调试工具,连接到gdbserver,并加载coredump文件,例如: ``` arm-linux-androideabi-gdb <path-to-binary> -ex "target remote :5039" -ex "core-file <filename>" ``` 其中,`<path-to-binary>`是应用程序的可执行文件路径,`<filename>`是coredump文件的路径和文件名。 7. 在gdb调试界面中,可以使用各种命令分析coredump文件的信息,例如查看寄存器状态、打印堆栈信息等。 需要注意的是,获取coredump文件需要root权限,而且对于系统级的crash,可能需要特殊的配置和调试工具才能捕获到完整的信息。此外,coredump文件可能会包含敏感信息,需要注意保密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值