自修改代码中的段错误

时间:2015-04-14 14:44:57

标签: c assembly x86-64 cpu-cache self-modifying

这与我曾经问过的Probable instruction Cache Synchronization issue in self modifying code?有关。即使已接受的解决方案解决了相关问题,我遇到了一种新的间歇性故障模式,其中CPU在重新打开功能后尝试跳转到垃圾地址。但事后的反汇编(使用核心转储)显示了调用指令中的正确地址。

接下来是一些gdb分析。

Program terminated with signal 11, Segmentation fault.
#0  0x00000000014010d0 in ?? ()
(gdb) bt
#0  0x00000000014010d0 in ?? ()
#1  0x0000000000492e01 in FastPelY_14 ()
#2  0x000000000045d85d in SubPelBlockMotionSearch ()
#3  0x0000000000467a23 in BlockMotionSearch ()
#4  0x0000000000469c99 in PartitionMotionSearch ()
#5  0x0000000000487bf7 in encode_one_macroblock ()
#6  0x0000000000496ccd in encode_one_slice ()
#7  0x0000000000426081 in code_a_picture ()
#8  0x000000000042766f in frame_picture ()
#9  0x000000000042664b in encode_one_frame ()
#10 0x0000000000430a23 in main ()

(gdb) disas /r 0x0000000000492e01
   0x0000000000492dfc <+38>:    e8 cf e2 f6 ff  callq  0x4010d0 
=> 0x0000000000492e01 <+43>:    8b 45 e4    mov    -0x1c(%rbp),%eax

这里要注意的有趣事情是,当正确的地址是0x4010d0时,垃圾地址在失败时总是 0x14010d0 。这让我觉得调用指令甚至以某种方式失败 - 尽管指令指针显示为指向回溯中的下一条指令。 (可能这是gdb的正确行为。我不太确定)。

所以如果是这样的话,显然CPU已经试图调用 e8 cf e2 f6 00 而不是 e8 cf e2 f6 ff 。最初生活在调用站点的5字节序列从0x0000000000492dfc开始,是一个5字节的NOP(根据在顶部链接的问题中给出的建议)0x0F1F440000。

有什么想法在这里发生了什么?如果需要更多背景,请告诉我。顺便说一句,我使用的是英特尔(R)Xeon(R)CPU E5-2670,但我尝试过的其他几台机器的行为似乎一致。

编辑:代码已使用以下附加选项进行编译,并具有-O2优化级别。

-fno-optimize-sibling-calls -finstrument-functions

0 个答案:

没有答案