MacOS如何解析系统库的符号?

一次崩溃的堆栈

如题,在分析这个crash时,顶层调用栈显示libdispatch.dylib::unknown,无法进一步定位crash的原因。

现象原因

这种现象多半是出问题的机器系统库过于老旧,和解dmp所在机器的系统库版本不一致,导致解dmp时无法匹配该系统库

解决方法

  1. 捞取log后,全局搜索os_version, 找到出问题的macOS系统版本,本例中是10.14.4

  2. 自行到搜索引擎下载对应版本macOS镜像的dmg文件

  1. 下载下来后,按如下图的路径找到系统库的dylib文件:

  1. 把dylib拷出来,用lldb -c xxx.dmp重新加载dmp文件,然后target symbol add xxx.dylib,即可加载刚下载的dylib文件。然后重新bt就可以找到系统库的符号,如下图,是crash在系统api:dispatch_block_cancel

  1. 或者用atos命令也可以找到符号,这个命令是把指定的地址转换为符号,需要知道两个地址,模块加载的基地址和实际的地址:

用lldb加载dmp后,image list可以查看所有已加载的模块列表,找到需要的模块,0x00007fff5b3db000就是基地址:

bt后跟在frame #x:后面的0x00007fff5b3e16fe是实际的地址,然后运行:

atos -o path/to/dylib -arch x86_64 -l 0x00007fff5b3db000 0x00007fff5b3e16fe,也可以得到函数名:

备注,用mindump_stackwalker解出来的结果,如果最后面显示某个模块是No symbol,同样可以佐证这个模块没有被成功加载:

附:

  1. 有时候发现用target symbol add自己另外下载的dylib后,再bt仍然没有函数名,需要用atos手动转,转出来的是正确的,猜测可能lldb已经加载了错误的dylib,如果没有把这个错误的卸载掉,那正确的可能不会生效,暂时没有找到解法,目前先用atos手动转

  2. macOS常见模块所在的路径:

系统库(以libsystem开头的)或c++库按下面路径查找:

framework相关的库:

如图:在Extensions或Frameworks目录下,注意kext文件可以右键--显示包内容

IOHIDLib在这里:

近期看了一些高版本(macOS 11.x, 12.x)的crash,发现在下载的系统镜像中已经无法找到dylib文件,猜测是苹果把这些二进制文件又做了一层压缩,所以现在如果还想解系统符号,估计只能装个和崩溃现场一模一样的系统了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值