转储Core时获取堆快照的时间

时间:2014-07-25 07:04:02

标签: c++ linux multithreading gdb coredump

我们有一个在Linux 2.6.32上运行的posix mutli-threaded C ++程序,它在其中一个线程中进行核心转储。使用gdb-7.2 corss-compiled分析核心文件,我们看到故障指令在这里

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

并在框架中注册:

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

这是有道理的,因为r9在进程/线程的上下文中具有无效的地址值(实际上是我们编写的堆擦除模式)。

令人困惑的一点是r9是从这样加载的

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

和r4包含(第一个和唯一的)函数参数&#34;数据&#34;的值。 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而不是模式&#34; 0xdeaddead&#34;这是在内存空闲时写入并返回堆中的。

所以,当内存包含合法对象时,为什么寄存器r9包含擦洗值。我的理论是核心包含内存的快照,就像进程死了一样,远远低于当实际崩溃发生时。在引发SIGSEGV之后,堆内存的这个位置仍然可以由其他线程使用,因为它们正在记录数据直到时间进程终止。因此,数据指向的内存可能已经被重新分配,并且在内存快照被捕获并被保存在核心中时被使用/被使用。

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

谢谢!

1 个答案:

答案 0 :(得分:-2)

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

请参阅How to write a signal handler to catch SIGSEGV?