我们有一个在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的地址/位置(通过其他线程)?
谢谢!
答案 0 :(得分:-2)
您是否为SIGSEGV
使用信号处理程序?它们是异步的还是可重入的?