2017-03-29 67 views
1

虽然试图分析广发行核心转储(过程由断言SIGABRT抛弃)我得到以下输出回溯:内核转储GDB“回溯停止:框架未保存PC”

(gdb) bt 
#0 0x76d6bc54 in raise() from ./lib/libc.so.1 
#1 0x76d63bb8 in abort() from ./lib/libc.so.1 
Backtrace stopped: frame did not save the PC 
(gdb) thread apply all bt 

的二进制文件是用“-g”编译的,因此除了工具链中的链接库(例如libc甚至没有符号),我都无法确定它是如何构建的。

这是堆栈损坏或者是它的libc的结果被用类似“fomit帧指针”编译。

仿佛未捕获的异常从运行链接库和库发生一般性的问题没有得到调试建会发生什么情况,即可以将信息转储仍然包含有用的信息?

由于

改善回溯其包括从共享对象功能而不调试符号

回答

0

一种方法是安装调试符号,其中的gdb可以看到它们。如何做的细节取决于你的环境。例如,如果libc.so.6libc6软件包在Debian系统上提供,则安装libc6-dbg软件包会在/usr/lib/debug/.build-idlibc6软件包,除libc.so.6之外,提供许多其他剥离的共享对象)下放置多个符号表。如果您使用的是调试环境非本地核心(由./lib/libc.so.1领先.所建议的),你可能会提取这样的包,而不是安装它(Debian系统dpkg -x上是这样做的一种方式)。

除了调试符号的问题,在某些情况下,您可以通过确保gdb看到的共享对象(剥离或其他方式)正确对应于转储过程中使用的共享对象来改善回溯核心。一种检查方法是比较file命令报告的构建ID(在典型的Linux系统上)。如果您可以可靠地确定在核心转储时使用哪些共享对象,并且它假设您的共享对象是以包含构建ID的方式构建的,则这只会有所帮助。

在某些情况下可执行的和生成的ID的所有相关的共享对象可以被可靠地从核心文件本身提取。在Linux系统上,这需要在核心中存在文件注释,并且需要存在可执行文件的第一页和每个共享对象。最近配置了典型默认值的Linux内核包括所有这些内核。

https://github.com/wackrat/structer提供,其提取从建立满足其假设一个核心文件ID Python代码。根据核心文件的大小,最好使用64位系统,即使核心本身来自32位系统也是如此。

如果事实证明gdb正在为该内核使用正确的共享对象(或者如果没有可行的方法来确认或反驳),另一种可能是反汇编由gdb报告的两个堆栈帧中的代码。如果gdb看到的共享库不适合这个核心,反汇编很可能是神秘的,因为gdb依赖于共享对象的内容,它在核心文件时使用该内容与该位置的内容对齐被转储(只读段通常被排除在核心文件之外,除了提供每个构建ID的第一页之外)。根据我的经验,gdb通常可以在没有调试符号的情况下提供连贯的回溯,即使没有帧指针,但是如果使用了错误的共享对象,gdb可能会根据与该位置的正确内容不相对应的指令进行回溯。

+0

Thanky Erik。我不知道你可以从coredump恢复共享对象,这意味着堆也被倾倒?我尝试运行structer,但由于某种原因,我遇到了[例外](https://hastebin.com/wudewixoko.sql) – Serj

+0

结构代码中的异常是由于核心文件的auxv中无法识别的段类型造成的; structer.elf.enums.PType需要更改以处理它,并且在异常处理代码中还有改进的空间。 –

0

我认为罪魁祸首是应用程序加载的libc。它可能编译了一些使coredump无用的选项。我所做的是创建一个自定义工具链(使用从buildroot编译的工具链),并使用该工具链编译和运行应用程序。然后我能够成功读取coredump。