转储核心时拍摄堆快照的时间



我们有一个运行在Linux 2.6.32上的posix多线程c++程序,它在其中一个线程中进行内核转储。使用gdb-7.2交叉编译分析核心文件,我们看到错误指令在这里

0x11491178 <+208>:   lwz     r0,8(r9)

和寄存器在帧中显示:

(gdb) info reg
r0             0x0      0
….
r9             0xdeaddead       3735936685

这是有意义的,因为r9在进程/线程上下文中有一个无效的地址值(实际上是我们写的堆擦洗模式)。

令人困惑的是r9是这样加载的

0x1149116c <+196>:   lwz     r9,0(r4)

和r4包含(第一个也是唯一一个)函数参数"data"的值。GDB告诉我以下关于数据的信息:

(gdb) p data
$6 = (TextProcessorIF *) 0x4b3fe858
(gdb) p *data
$7 = {_vptr.TextProcessorIF = 0x128b5390}
(gdb) info symbol 0x128b5390
vtable for TextProcessorT<unsigned short> + 8 in section .rodata 

在这个上下文中都是正确的。所以r9的值应该是0x128b5390,而不是模式"0xdeaddead",这是在内存被释放并返回堆时写入的。

那么,为什么当内存中包含合法对象时,寄存器r9包含擦除值。我的理论是,内核包含内存的快照,就像进程死亡时,这是在实际崩溃发生时更进一步的线。在SIGSEGV被触发之后,堆内存的这个位置仍然可以被其他线程使用,因为它们正在记录数据,直到时间进程结束。因此,数据所指向的内存可能已经被重新分配,并且在内存快照被拍摄并保存在内核中时正在使用/被使用。

我的问题是:
A)我的理论正确吗?
B)我是否正确地假设堆内存快照不是在崩溃时拍摄的(信号被提出),而是在进程的最后时刻?
C)地址/位置导致SIGSEGV仍然可以使用(由其他线程)?

谢谢!

您是否使用SIGSEGV的信号处理程序?它们是异步的和可重入的吗?

参见如何编写一个信号处理程序来捕获SIGSEGV?

最新更新