2011-01-16 29 views
24

Tôi đã nhìn thấy nhiều bãi lõi trong cuộc sống của tôi, nhưng điều này đã cho tôi stumped."Không thể giải thích" lõi dump

Bối cảnh:

  • đa luồng Linux chương trình/x86_64 chạy trên một cụm AMD Barcelona CPU
  • mã mà treo được thực hiện một nhiều
  • chạy 1000 trường hợp của chương trình (các chính xác cùng một nhị phân tối ưu hóa) dưới tải sản xuất 1-2 tai nạn mỗi giờ
  • sự cố xảy ra trên các máy khác nhau (nhưng bản thân máy khá giống nhau)
  • treo tất cả đều giống nhau (địa chỉ chính xác, cùng gọi stack)

Dưới đây là các chi tiết của vụ tai nạn:

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> 

Bạn sẽ nhận thấy rằng vụ tai nạn đã xảy ra trong giữa hướng dẫn tại 0x17bd9fc, sau khi trả lời từ một cuộc gọi tại 0x17bd9f6 đến một chức năng ảo.

Khi tôi kiểm tra bảng ảo, tôi thấy rằng nó không phải là hỏng dưới mọi hình thức:

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

và rằng nó chỉ ra chức năng tầm thường này (như mong đợi bằng cách nhìn vào nguồn):

(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. 

Hơn nữa, khi tôi nhìn vào địa chỉ trả lại rằng Foo1::Get() nên đã quay trở lại:

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

Tôi thấy rằng nó trỏ đến đúng hướng dẫn, vì vậy nó giống như trong quá trình trở về từ Foo1::Get(), một số gremlin xuất hiện và tăng lên %rip bởi 4.

Giải thích hợp lý?

+0

Bạn đã bao giờ tìm hiểu nguyên nhân gây ra điều này? Nếu vậy, tôi rất muốn nghe nó là gì! – us2012

+1

@ us2012 Tôi tin rằng chúng tôi đã tìm ra nguyên nhân. Xem câu trả lời của tôi. –

Trả lời

27

Vì vậy, dường như có vẻ như chúng tôi dường như không gặp phải lỗi CPU thực tế nào.

http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf có lỗi thuộc về # 721:

721 Processor May không đúng Cập nhật Stack Pointer

Mô tả

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. 

Hiệu lực tiềm năng trên hệ thống

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). 
+0

Ouch. Nó thực sự là một điều kiện "rất cụ thể" - tức là, bạn đã quản lý để sửa chữa nó bằng cách thay đổi một chút mã được sản xuất tại điểm có vấn đề? – us2012

+8

@ us2012 Mã và trình biên dịch của chúng tôi liên tục thay đổi và vấn đề biến mất đột ngột khi nó xuất hiện ... chỉ xảy ra lại sau 2 năm trong một tệp thực thi hoàn toàn không liên quan. –

3

Tôi từng thấy lỗi "mã hóa bất hợp pháp" ở giữa lệnh. Tôi đã làm việc trên một cổng Linux. Dài câu chuyện ngắn, Linux trừ từ các con trỏ hướng dẫn để khởi động lại một syscall, và trong trường hợp của tôi điều này đã xảy ra hai lần (nếu hai tín hiệu đến cùng một lúc).

Vì vậy, đó là một thủ phạm có thể xảy ra: hạt nhân đang sử dụng con trỏ của bạn. Có thể có một số nguyên nhân khác trong trường hợp của bạn.

Lưu ý rằng đôi khi trình xử lý sẽ hiểu dữ liệu mà nó xử lý dưới dạng hướng dẫn, ngay cả khi nó không được cho là. Vì vậy, bộ vi xử lý có thể đã thực hiện "lệnh" tại 0x17bd9fa và sau đó chuyển sang 0x17bd9fd và sau đó tạo ra một ngoại lệ opcode bất hợp pháp. (Tôi vừa tạo ra con số đó, nhưng thử nghiệm với một bộ tách rời có thể cho bạn thấy nơi mà bộ vi xử lý có thể đã "nhập" vào dòng lệnh.)

Gỡ lỗi hạnh phúc!

+0

Tôi đã xem xét các tín hiệu, nhưng có một số "cảnh cáo" chống lại chúng là nguyên nhân: 1. lưu ý rằng không có cuộc gọi hệ thống ở bất kỳ đâu xung quanh mã này; 2. chủ đề này không nên nhận bất kỳ tín hiệu async; 3. nếu một tín hiệu đã gây ra điều này, làm thế nào để bạn giải thích sự cố xảy ra trên * chính xác * cùng một địa chỉ trong tất cả các chương trình bị rơi? –

+0

Tôi không đề xuất vấn đề của bạn có thể là tín hiệu. (Đó chỉ là lỗi trong cổng phía sau vấn đề của tôi). Quan điểm của tôi là các yếu tố hoàn toàn nằm ngoài chương trình của bạn - giống như một lỗi hạt nhân - có thể gây ra vấn đề này. Một thứ khác có thể gây rối với con trỏ của bạn là xử lý ngoại lệ. – Artelius

Các vấn đề liên quan