2011-01-16 20 views
24

मैंने अपने जीवन में कई कोर डंप देखे हैं, लेकिन यह मुझे स्टंप कर चुका है।"अस्पष्ट" कोर डंप

प्रसंग:

  • मल्टी-थ्रेडेड लिनक्स/x86_64 कार्यक्रम AMD Barcelona सीपीयू
  • के एक समूह पर चल रहा है कोड है कि दुर्घटनाओं कार्यक्रम का एक बहुत
  • चल 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) x/a $rsp-8 
0x2afa55602048: 0x17bd9f9 <_Z3Foov+345> 
:
(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() को लौट जाना चाहिए था कि

मैं देख रहा हूँ कि यह सही शिक्षा की ओर इशारा करता है, इसलिए यह रूप में अगर है Foo1::Get() से लौटने के दौरान, कुछ दुष्टात्मा साथ आया था और 4.

प्रशंसनीय स्पष्टीकरण %rip वृद्धि की जाती?

+0

क्या आपने कभी यह पता लगाया कि इसका क्या कारण है? यदि हां, तो मुझे यह जानने में बहुत दिलचस्पी होगी कि यह क्या था! – us2012

+1

@ us2012 मुझे विश्वास है कि हमें कारण मिला है। मेरा जवाब देखें –

उत्तर

27

तो, ऐसा लगता है कि ऐसा लगता है कि ऐसा लगता है कि हम वास्तविक वास्तविक-सीपीयू बग को हिट करते हैं।

721 प्रोसेसर मई को गलत तरीके से अद्यतन ढेर सूचक

विवरण

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. 

संभावित सिस्टम

पर प्रभाव:

http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf इरेटा # 721 है

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

ओच। क्या यह वास्तव में एक "अत्यधिक विशिष्ट" स्थिति है - यानी, क्या आपने समस्याग्रस्त बिंदु पर उत्पादित कोड को थोड़ा बदलकर इसे ठीक करने का प्रबंधन किया था? – us2012

+8

@ us2012 हमारे कोड और कंपाइलर लगातार बदल रहे हैं, और अचानक प्रकट होने पर समस्या गायब हो गई ... केवल 2 साल बाद पूरी तरह से असंबंधित निष्पादन योग्य में। –

3

मैंने एक बार निर्देश के बीच में "अवैध ओपोड" क्रैश देखा है। मैं एक लिनक्स पोर्ट पर काम कर रहा था। लंबी कहानी छोटी, लिनक्स एक सिस्कोल को पुनरारंभ करने के लिए निर्देश सूचक से घटाता है, और मेरे मामले में यह दो बार हो रहा था (यदि दो सिग्नल एक ही समय में पहुंचे)।

तो यह एक संभावित अपराधी है: कर्नेल आपके निर्देश सूचक के साथ झुकाव। आपके मामले में कुछ और कारण हो सकता है।

ध्यान रखें कि कभी-कभी प्रोसेसर उस डेटा को समझ लेगा जो यह एक निर्देश के रूप में प्रसंस्करण कर रहा है, भले ही यह नहीं होना चाहिए। तो प्रोसेसर ने 0x17bd9fa पर "निर्देश" निष्पादित किया हो सकता है और फिर 0x17bd9fd पर ले जाया गया और फिर एक अवैध opcode अपवाद उत्पन्न किया। (मैंने अभी उस नंबर को बनाया है, लेकिन डिस्सेबलर के साथ प्रयोग करने से आपको पता चल सकता है कि प्रोसेसर ने निर्देश स्ट्रीम "प्रवेश" की हो सकती है।)

हैप्पी डिबगिंग!

+0

मैंने संकेतों पर विचार किया है, लेकिन उनके खिलाफ कई "स्ट्राइक" हैं: 1. ध्यान दें कि इस कोड के आस-पास कहीं भी सिस्टम कॉल नहीं हैं; 2. यह धागा किसी भी async सिग्नल प्राप्त नहीं करना चाहिए; 3. अगर कोई सिग्नल इसका कारण बन रहा था, तो आप सभी दुर्घटनाग्रस्त कार्यक्रमों में * सटीक * एक ही पते पर होने वाली दुर्घटना को कैसे समझाते हैं? –

+0

मैंने सुझाव नहीं दिया कि आपकी समस्या सिग्नल हो सकती है। (यह मेरी समस्या के पीछे बंदरगाह में बस बग था।) मेरा मुद्दा यह था कि आपके प्रोग्राम के लिए पूरी तरह से बाहरी कारक - जैसे कर्नेल बग - इस समस्या का कारण बन सकता है। एक और चीज जो आपके निर्देश सूचक के साथ गड़बड़ कर सकती है अपवाद हैंडलिंग है। – Artelius

संबंधित मुद्दे