2009-06-26 12 views
13

मेरे पास एक सी साइट है जिसे हमने किसी ग्राहक साइट पर तैनात किया है। यह संकलित और एचपी-यूएक्स पर चलता है। उपयोगकर्ता ने एक दुर्घटना की सूचना दी है और हमने कोर डंप प्राप्त किया है। अब तक, मैं घर में दुर्घटना को डुप्लिकेट करने में असमर्थ रहा हूं।कोई प्रतीक के साथ डीबग कोर फ़ाइल

जैसा कि आपको संदेह होगा, मूल फ़ाइल/तैनात निष्पादन योग्य किसी भी प्रकार के प्रतीकों से पूरी तरह से रहित है। जब मैंने इसे gdb में लोड और एक bt करते हैं, सबसे अच्छा मैं यह है:

(gdb) bt 
#0 0xc0199470 in ??() 

मैं फ़ाइल पर एक 'तार कोर' कर सकते हैं, लेकिन मेरी समझ है सब मैं वहाँ मिलता है कि सभी निष्पादन योग्य में तार, तो ऐसा लगता है कि वहां कुछ भी ट्रैक करना असंभव लगता है।

मेरे पास निष्पादन योग्य के एक डीबग संस्करण (comp के साथ संकलित) है, दुर्भाग्य से रिलीज़ संस्करण की तुलना में कुछ महीने नए हैं।

warning: exec file is newer than core file. 
Core was generated by `program_name'. 
Program terminated with signal 11, Segmentation fault. 
__dld_list is not valid according to __dld_flags. 

#0 0xc0199470 in ??() 
(gdb) bt 
#0 0xc0199470 in ??() 

यह एक डिबग संस्करण संकलन और ग्राहक की साइट पर यह तैनाती और फिर एक और दुर्घटना के लिए प्रतीक्षा करने संभव होगी, यह अपेक्षाकृत मुश्किल होगा: अगर मुझे लगता है कि हब के साथ gdb प्रारंभ करने का प्रयास है, मैं यह देख और कई कारणों से अवांछनीय।

मैं कोड से काफी परिचित हूं और ग्राहक के बग रिपोर्ट के आधार पर कोड में कहां क्रैश हो रहा है, इसके बारे में अपेक्षाकृत अच्छा विचार है।

क्या कोई तरीका है कि मैं इस कोर डंप से कोई और जानकारी प्राप्त कर सकता हूं? तारों या किसी अन्य डीबगर या कुछ के माध्यम से? धन्यवाद।

उत्तर

7

gdb से प्रतिक्रिया के इस प्रकार:

(gdb) bt 
#0 0xc0199470 in ??() 

भी मामला है कि ढेर एक बफर लंघन, जहां वापसी पता स्मृति में ओवरराइट किया गया द्वारा तोड़ी गई थी में हो सकता है, तो प्रोग्राम काउंटर करने के लिए सेट हो जाता है एक प्रतीत होता है यादृच्छिक क्षेत्र।

यह एक तरीका है कि एक समान प्रतीक डेटाबेस के साथ भी एक निर्माण लुकअप त्रुटि (या अजीब लग रही बैकट्रैस) का कारण बन सकता है। यदि आपको प्रतीक तालिका होने के बाद भी यह मिलता है, तो आपकी समस्या यह है कि आपके ग्राहक का डेटा आपके कोड के साथ कुछ समस्याएं पैदा कर रहा है।

+0

यह उत्तर मुझे हास्यास्पद रूप से लगता है। मैं निश्चित रूप से संभावित रूप से ओवररन क्षेत्रों के लिए कोड को देखता हूं। – Morinar

+0

यदि "डुप्लिकेट" प्रतिलिपि के साथ डीबगिंग कुछ भी नहीं दिखाती है, तो अब पंजीकरण करने और स्टैक डंप को देखना शुरू करने का समय है कि आप कहीं भी बीच में कैसे पहुंचे। यह एक उड़ा हुआ (या अनियंत्रित) फ़ंक्शन पॉइंटर, आवंटन ओवररन, या शायद एक गलत बफर आकार या बफर उड़ाने वाले "खराब" इनपुट भी हो सकता है (अनियंत्रित इनपुट आदि के साथ sprintf()/sscanf का उपयोग करके)। – jesup

+0

मैंने कभी यहां कुछ भी नहीं देखा है, लेकिन मैं इसे स्वीकार कर रहा हूं क्योंकि यह अभी भी सबसे अधिक संभावना होने जैसा लगता है। – Morinar

1

क्या आपके पास सटीक स्रोत है जिसका उपयोग आपने पुराने संस्करण को संकलित करने के लिए किया था (उदाहरण के लिए, स्रोत पेड़ में किसी टैग के माध्यम से या ऐसा कुछ)? हो सकता है कि आप इसका उपयोग करके पुनर्निर्माण कर सकें, और संभवतः दुर्घटनाग्रस्त होने पर अंतर्दृष्टि प्राप्त हो सकती है?

+0

मेरे पास सटीक स्रोत है, लेकिन कोड के इस विशेष टुकड़े में उस बिंदु से बहुत कुछ नहीं बदला गया है (यदि बिलकुल नहीं)। – Morinar

0

यहां अधिक जानकारी नहीं है। बाइनरी छीन ली गई है। लेकिन सेगमेंटेशन गलती को देखते हुए ... आपको उन स्थानों की तलाश करनी चाहिए जहां एक संभावना है कि आप स्मृति के एक टुकड़े को ओवरराइट कर रहे हैं।

यह सिर्फ एक सुझाव है। कई समस्याएं हो सकती हैं।

बीटीडब्ल्यू, यदि आप अपनी स्थानीय मशीन में पुन: उत्पन्न करने में सक्षम नहीं हैं तो ग्राहकों की डेटा की मात्रा एक समस्या हो सकती है।

5

भविष्य के लिए:

  1. यह सुनिश्चित करें कि आप हमेशा एक बाहरी प्रतीकों डाटाबेस के साथ निर्माण बनाओ (यह एक डीबग बिल्ड नहीं है - यह एक रिलीज के निर्माण है, लेकिन आप प्रतीक तालिका अलग से स्टोर)
  2. आप

तैनात इस स्थिति के लिए संस्करणों के लिए इसके चारों ओर रखें:

आप सामान्य क्षेत्र पता है, इसलिए यदि आप ठीक कह रहे हैं देखने के लिए, ढेर tra के लिए जाना सीई और असेंबली कोड ढूंढें - इसे नजरअंदाज करें और देखें कि क्या आपको लगता है कि यह आपके स्रोत से मेल खाता है (यह आसान है अगर आपको पता है कि इस असेंबली ने किस स्रोत को उत्पन्न किया है)। यदि यह सही दिखता है, तो आपके पास अपनी परिकल्पना पर कुछ सत्यापन है। आप स्टैक को देखकर स्थानीय चर के मानों को समझने में सक्षम हो सकते हैं (क्योंकि आप जानते हैं कि आपने क्या पारित किया है और घोषित किया है)।

+0

मैं असेंबली कोड कैसे ढूंढूं और/या स्टैक ट्रेस पर कैसे जा सकता हूं? मैंने देखा है कि अब तक के सभी स्टैक ट्रेस मैंने ऊपर चिपकाया है ... – Morinar

+0

कमांड 'डिससेम्बल' है - यह देखें http://www.unknownroad.com/rtfm/gdbtut/gdbadvanced.html –

+0

मैंने किया यह और मिला: (gdb) को अलग करें किसी फ़ंक्शन में चयनित फ्रेम के लिए प्रोग्राम काउंटर शामिल नहीं है। जो मुझे लगता है जैसे यह सूफियन द्वारा सुझाए गए स्मैश स्टैक का समर्थन करता है। – Morinar

2
  1. हमेशा उपयोग स्रोत नियंत्रण (सीवीएस/GIT/सबवर्सन/आदि), यहां तक ​​कि परीक्षा विज्ञप्ति
  2. टैग सभी विज्ञप्ति (भविष्य में)
  3. पर विचार करें डिबगिंग के साथ एक निर्माण करने के लिए (- जी) और शिपिंग से पहले निष्पादन योग्य पट्टी। नोट: दो बिल्डों को बिना और बिना बनाओ; वे अच्छी तरह से मेल नहीं खा सकते हैं, क्योंकि -जी अवसर पर भी उसी अनुकूलन स्तर पर उत्पन्न होने वाले विभिन्न कोड का कारण बन सकता है। सुपर-प्रदर्शन-महत्वपूर्ण कोड में आप महत्वपूर्ण फाइलों के लिए -g को छोड़ सकते हैं - अधिकतर इससे कोई फर्क नहीं पड़ता है।
  4. यदि आप वास्तव में अटक गए हैं, ढेर को डंप करें और ढेर के प्रासंगिक हिस्सों को हेक्स पर डंप करें और इसे हाथ से देखें; शायद एक वाद्ययंत्र प्रतिलिपि लेना और जेनरेट कोड और स्टैक पर समान "हस्ताक्षर" ढूंढना। यह असली "पुराने स्कूल" डीबगिंग है ... :-)
+0

निश्चित रूप से ठोस सलाह। हम यहां बहुत से कदम 1-3 करते हैं, लेकिन इस पर ध्यान दिए बिना, उन्हें स्वयं के मुकाबले लोगों के एक पूरी तरह से अलग सेट (हमारे पास उन चीजों का प्रभारी दल है) द्वारा संभाला जाता है। – Morinar

3

gdb के अंतर्गत, "जानकारी रजिस्टर" आप दुर्घटना के समय की एक disassembly के साथ उपयोग करने के लिए पर्याप्त निष्पादन राज्य के देना चाहिए निष्पादन योग्य और प्रासंगिक साझा पुस्तकालयों। मैं आम तौर पर डिस्सेम्बल करने के लिए objdump का उपयोग करता हूं, एक फ़ाइल में आउटपुट रीडायरेक्ट करता हूं, फिर फ़ाइल को अपने पसंदीदा संपादक में लाता हूं - यह नोट्स रखने के लिए उपयोगी है क्योंकि चीजों को समझ लिया जाता है। इसके अलावा जीडीबी की "जानकारी लक्ष्य" और "जानकारी साझालिब" यह पता लगाने के लिए उपयोगी हो सकती है कि साझा पुस्तकालयों को लोड किया गया है।

रजिस्टर राज्य, स्टैक सामग्री और थोड़ी किस्मत के साथ हाथ में अलग-अलग हिस्सों के साथ, कॉलस्टैक का पुनर्निर्माण करने के लिए यह सीधा होना चाहिए (जब तक, बेशक, स्टैक को बफर ओवररन या इसी तरह से ट्रैश किया गया है आपदा ... उस मामले में एक Ouija बोर्ड या क्रिस्टल बॉल की आवश्यकता हो सकती है।)

आप स्ट्रिप किए गए संस्करण के डिस्सेप्लर के खिलाफ-साथ बनाए गए नए संस्करण के एए डिस्सेप्लोर को सहसंबंधित करने में भी सक्षम हो सकते हैं।

1

कोर फ़ाइल के विरुद्ध "pmap" चलाने का प्रयास करें (यदि एचपी/ux में यह टूल है)। यह कोर फ़ाइल में सभी मॉड्यूल के शुरुआती पतों की रिपोर्ट करनी चाहिए। इस जानकारी के साथ, आप विफलता स्थान का पता ले सकते हैं और पता लगा सकते हैं कि कौन सी लाइब्रेरी दुर्घटनाग्रस्त हो गई है। क्रैश पता और लाइब्रेरी में ज्ञात कार्यों के पते के बीच और पता तुलना (पुस्तकालय के विरुद्ध "एनएम" प्राप्त करना चाहिए) यह निर्धारित करने में आपकी सहायता कर सकता है कि कौन सा फ़ंक्शन क्रैश हो गया है।

भले ही आप स्टैक के शीर्ष पर फ़ंक्शन की पहचान करने का प्रबंधन करते हैं, यह भी संभावना नहीं है कि यह फ़ंक्शन समस्या का स्रोत है ... उम्मीद है कि यह वास्तव में आपके कोड में क्रैश हो गया है और नहीं, कहें , मानक सी स्ट्रिंग लाइब्रेरी। स्टैक ट्रेस को पुनर्निर्माण करना उस बिंदु पर अगली सबसे अच्छी बात है।

0

मुझे नहीं लगता कि मूल फ़ाइल में प्रतीक होना चाहिए। आपको अपने प्रोग्राम का एक संस्करण बनाने में सक्षम होना चाहिए जो बिल्कुल उसी जैसा आपने अपने ग्राहक को भेजा था, लेकिन साथ-साथ।यदि आप अपना डीबग निष्पादन योग्य पट्टी करते हैं, तो यह शिप किए गए संस्करण के समान होना चाहिए। केवल तभी जीडीबी आपको कुछ भी उपयोगी दे सकता है।

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