linux - "Unexplainable"核心转储

标签 linux segmentation-fault x86-64

我这辈子见过很多核心转储,但这个让我难住了。

上下文:

  • AMD Barcelona 集群上运行的多线程 Linux/x86_64 程序CPU
  • 崩溃的代码执行了很多
  • 在负载下运行 1000 个程序实例(完全相同的优化二进制文件)每小时会产生 1-2 次崩溃
  • 崩溃发生在不同的机器上(但机器本身非常相同)
  • 崩溃看起来都一样(相同的确切地址,相同的调用堆栈)

以下是崩溃的详细信息:

Program terminated with signal 11, Segmentation fault.
#0  0x00000000017bd9fd in Foo()
(gdb) x/i $pc
=> 0x17bd9fd <_Z3Foov+349>: rex.RB orb $0x8d,(%r15)

(gdb) x/6i $pc-12
0x17bd9f1 <_Z3Foov+337>:    mov    (%rbx),%eax
0x17bd9f3 <_Z3Foov+339>:    mov    %rbx,%rdi
0x17bd9f6 <_Z3Foov+342>:    callq  *0x70(%rax)
0x17bd9f9 <_Z3Foov+345>:    cmp    %eax,%r12d
0x17bd9fc <_Z3Foov+348>:    mov    %eax,-0x80(%rbp)
0x17bd9ff <_Z3Foov+351>:    jge    0x17bd97e <_Z3Foov+222>

您会注意到崩溃发生在 0x17bd9fc 指令的中间,也就是从 0x17bd9f6 调用返回之后一个虚函数。

当我检查虚拟表时,我发现它没有以任何方式损坏:

(gdb) x/a $rbx
0x2ab094951f80: 0x3f8c550 <_ZTI4Foo1+16>
(gdb) x/a 0x3f8c550+0x70
0x3f8c5c0 <_ZTI4Foo1+128>:  0x2d3d7b0 <_ZN4Foo13GetEv>

并且它指向这个微不足道的函数(正如查看源代码所预期的那样):

(gdb) disas 0x2d3d7b0
Dump of assembler code for function _ZN4Foo13GetEv:
   0x0000000002d3d7b0 <+0>: push   %rbp
   0x0000000002d3d7b1 <+1>: mov    0x70(%rdi),%eax
   0x0000000002d3d7b4 <+4>: mov    %rsp,%rbp
   0x0000000002d3d7b7 <+7>: leaveq 
   0x0000000002d3d7b8 <+8>: retq   
End of assembler dump.

此外,当我查看 Foo1::Get() 应该返回的返回地址时:

(gdb) x/a $rsp-8
0x2afa55602048: 0x17bd9f9 <_Z3Foov+345>

我看到它指向正确的指令,所以就好像在从 Foo1::Get() 返回期间,一些 gremlin 出现并增加了 %rip 4.

合理的解释?

最佳答案

因此,尽管看起来不太可能,但我们似乎遇到了真正的 CPU 错误。

http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf有错误#721:

721 处理器可能错误地更新堆栈指针

Description

Under a highly specific and detailed set of internal timing conditions,
the processor may incorrectly update the stack pointer after a long series
of push and/or near-call instructions, or a long series of pop 
and/or near-return instructions. The processor must be in 64-bit mode for
this erratum to occur.

Potential Effect on System

The stack pointer value jumps by a value of approximately 1024, either in
the positive or negative direction.
This incorrect stack pointer causes unpredictable program or system behavior,
usually observed as a program exception or crash (for example, a #GP or #UD).

关于linux - "Unexplainable"核心转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4703844/

相关文章:

linux - 如何在多个服务器中搜索目录?

在终端上找不到 Python 模块,但在 Python shell、Linux 上找到

c - 像这样使用 malloc 有什么问题?

c - "lea"炸弹实验室第 4 阶段命令

linux - 如何将 stderr 和 stdout 重定向到多个输出文件?

linux - Bash 字符串替换,查找父路径

c++ - 成功调用析构函数或调用 empy 析构函数后出现段错误。 C++

c++ - Tesseract OCR QT 错误

c - 将地址弹出到寄存器中

c - 为什么编译器会在编译的汇编代码中生成额外的 sqrts