通过反汇编解析crash问题

背景:

用户反馈的问题,有时候我们拿到log,发现有crash问题,有堆栈打印,能看到具体出错的函数,但是无法定位具体出错的行数和内容,这个时候就需要用到反汇编辅助我们定位问题。

反汇编方法:

通过objdump反汇编so:

objdump -d ~/shared/libxxx.so > ~/aaa.s

这样反汇编的内容就会保存到aaa.s文件中

demo查看crash问题:

首先从上面的log可以看出,程序crash的原因为signal 11 也就是空指针问题,具体出错的地址是: 0x00000000000000b8, 也就是这个地址里面存放的是空。从backtrace可以看到,出错的函数是TeaInsideSdk::Engine::OnRecvMessage,在这个函数里面,调用的下一步的函数入口是出错的地址: 0x00000000000000b8。也就是说,出错的地址是一个指针,指向了一个函数。

然后我们就可以从反汇编的文件继续查看,其中出错前执行的是00000000000b2810,所以直接从此处查看反汇编。

对应的反汇编就是这段代码。

从上面的反汇编代码可以看出,首先是调用了ParseDeviceControlResponseParams函数,然后调用了notify,然后做了一系列处理,最终出错。此时需要看c++代码,定位位置:

通过TeaInsideSdk::Engine::OnRecvMessage和ParseDeviceControlResponseParams关键信息可以定位对应代码如下:

上面的信息汇总来看,x1就是delegate_,x4就是delegate_的虚函数地址,x5就是delegate_->OnDeviceControlResult函数的入口地址。

所以,出错的原因就是OnDeviceControlResult这个函数调用失败。

查看delegate_对应的类,发现我们有新加一个虚函数,所以定位问题可能是客户拿到我们的sdk后,替换了so,但是未替换头文件导致。因为so中保存的虚函数表和头文件中不一致,所以运行出错。客户更新头文件后运行成功。

知识课堂:

crash log中的信息说明:

fault addr: (错误地址)是指在发生段错误(Segmentation Fault,信号为 SIGSEGV)时,程序试图访问的内存地址。在这个例子中

pc列表示导致段错误(SIGSEGV)的指令所在的地址。每一行对应一个栈帧(stack frame),表示调用链中的一个函数调用。栈帧从底部到顶部表示调用顺序,即底部的函数先被调用,顶部的函数后被调用

x0 至 x28:这些是ARM64架构的通用寄存器,用于存储临时数据和函数参数。

lr(链接寄存器):在函数调用过程中,这个寄存器保存了返回地址,即函数执行完毕后要跳转到的地址。在这个例子中,它的值为:0000007613cc4814。

sp(栈指针寄存器):这个寄存器指向当前栈顶的位置。在这个例子中,它的值为:000000760b41dac0。

pc(程序计数器):这个寄存器存储了当前正在执行的指令的地址。在这个例子中,它的值为:00000000000000b8。

pst(程序状态寄存器):这个寄存器包含了处理器的状态信息,如条件标志、中断使能等。在这个例子中,它的值为:0000000080001000。

汇编指令说明:

MOV - 将数据从一个位置复制到另一个位置。
JMP - 无条件跳转到指定的地址
LDR - Load Register,用于将内存中的数据加载到寄存器中
CBZ - Compare and Branch on Zero,如果寄存器的值为零,则跳转到指定的地址。
BL - Branch with Link,用于跳转到指定的地址,并将当前指令的地址保存到链接寄存器(LR)中,以便在返回时使用。
BLR - Branch with Link and Return,这是一个特殊的BL指令,用于跳转到链接寄存器(LR)中存储的地址,并从该地址处的函数返回

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值