3

这与自修改代码中可能的指令缓存同步问题有关?我曾经问过一段时间。尽管公认的解决方案解决了相关问题,但我遇到了一种新的间歇性故障模式,在该模式下,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。最初在呼叫站点从 0x0000000000492dfc 开始的 5 字节序列是 0x0F1F440000 的 5 字节 NOP(根据顶部链接的问题中给出的建议)。

有什么想法吗?如果需要更多上下文,请告诉我。顺便说一句,我使用的是 Intel(R) Xeon(R) CPU E5-2670,但我尝试过的其他几台机器的行为似乎是一致的。

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

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

4

0 回答 0