GDB调试core dump时如何在backtrace中显示.so共享库名称
解答
core dump是否存储共享对象/可执行文件名称信息?
默认配置生成的core dump包含这些信息。core文件中会持久化存储进程崩溃时的虚拟内存映射表,其中就记录了每个加载的可执行文件、共享对象(.so)的基地址范围、原始文件路径。你当前看到栈回溯全是??(),是因为GDB在本地环境找不到对应路径的匹配文件,无法完成地址和文件的关联显示,并非core本身没有存储相关数据。
可行的获取方法
你可以通过以下步骤直接从core文件中提取需要的.so名称,无需提前搭建完整调试环境:
- 第一步:导出进程映射信息
你可以任选以下任意一种方式获取所有加载文件的地址范围和路径:- 方式1:在GDB中加载core文件后,直接执行命令
info proc mappings,无需加载任何符号即可输出所有内存段对应的文件路径、起始/结束地址。 - 方式2:不用启动GDB,直接执行命令
readelf -n <你的core文件路径>,输出结果中的NT_FILE段会列出所有加载的可执行文件、.so的路径和地址区间。
- 方式1:在GDB中加载core文件后,直接执行命令
- 第二步:地址匹配得到对应.so名称
将栈回溯中每个栈帧的十六进制地址,和上一步得到的地址范围做对比,地址落在哪个.so的区间内,该栈帧就属于对应的.so。比如你提供的栈帧中0x00007f1169d3ba5b,如果落在0x00007f1169d30000 - 0x00007f1169d50000区间,而该区间对应的文件是libbusiness.so,就说明#6栈帧属于libbusiness.so。 - 第三步:优化调试流程
后续拿到需要的对应.so后,在GDB中执行set solib-search-path <你存放.so的本地目录>,再执行bt命令,GDB会自动将对应栈帧的.so名称显示出来,不需要提前准备全量的组件文件。
注意:拉取的.so需要和生成core时运行的版本完全一致,否则会出现地址匹配错误的问题。加密的.so只要你能拿到对应版本的文件,哪怕没有调试符号,也可以正常完成路径匹配显示。
内容的提问来源于stack exchange,提问作者Lukasz Kamisinski
相关产品推荐
相关产品推荐

