GDB को निष्पादन योग्य के साथ-साथ कोर डंप की आवश्यकता क्यों है?


11

मैं कोर डंप का उपयोग कर डिबग कर रहा हूं, और ध्यान दें कि gdb को आपको निष्पादन योग्य के साथ-साथ कोर डंप की आपूर्ति करने की आवश्यकता है। ऐसा क्यों है? यदि कोर डंप में वह सभी मेमोरी होती है जो प्रक्रिया उपयोग करती है, तो निष्पादन योग्य कोर डंप के भीतर नहीं है? शायद इस बात की कोई गारंटी नहीं है कि पूरे निर्वासन को मेमोरी में लोड किया गया है (व्यक्तिगत निष्पादन आमतौर पर इतने बड़े नहीं होते हैं) या शायद कोर डंप में सभी प्रासंगिक मेमोरी नहीं होती है? क्या यह प्रतीकों के लिए है (शायद वे आम तौर पर मेमोरी में लोड नहीं होते हैं)?


1
निष्पादन योग्य में प्रतीक जानकारी शामिल है, जैसा कि gdb प्रलेखन में उल्लेख किया गया है ...
थॉमस डिकी

1
हैरानी की बात है, कोई जवाब नहीं (केवल एक जोड़ा मैं) DWARF प्रारूप का उल्लेख
Basile Starynkevitch

जवाबों:


15

कोर डंप आपके प्रोग्राम मेमोरी फुटप्रिंट का सिर्फ डंप है, अगर आपको पता है कि जहां सब कुछ था तो आप बस उसी का उपयोग कर सकते थे।

आप निष्पादन योग्य का उपयोग करते हैं क्योंकि यह बताता है कि (तार्किक पते के संदर्भ में) चीजें मेमोरी में कहाँ स्थित हैं, अर्थात कोर फ़ाइल।

यदि आप एक कमांड का उपयोग करते हैं तो objdumpयह निष्पादन योग्य वस्तु के बारे में मेटा डेटा को डंप करेगा जिसे आप जांच कर रहे हैं। उदाहरण के रूप में a.out नाम की एक निष्पादन योग्य वस्तु का उपयोग करना।

objdump -h a.outहेडर की जानकारी को केवल डंप करता है, आपको उदाहरण के लिए अनुभाग दिखाई देंगे। .data या .bss या .text (वहाँ कई और अधिक कर रहे हैं)। ये कर्नेल लोडर को सूचित करते हैं कि ऑब्जेक्ट में विभिन्न खंड कहाँ पाए जा सकते हैं और कहाँ प्रक्रिया पते में सेक्शन को लोड किया जाना चाहिए, और कुछ वर्गों (जैसे .डाटा .text) के लिए क्या लोड किया जाना चाहिए। (.bss अनुभाग में फ़ाइल में कोई डेटा शामिल नहीं है, लेकिन यह असमान डेटा के लिए प्रक्रिया में आरक्षित करने के लिए मेमोरी की मात्रा को संदर्भित करता है, यह शून्य से भरा है)।

निष्पादन योग्य ऑब्जेक्ट फ़ाइल का लेआउट एक मानक, ईएलएफ के अनुरूप है।

objdump -x a.out - सब कुछ डंप

यदि निष्पादन योग्य वस्तु में अभी भी अपने प्रतीक टेबल हैं (इसे छीन नहीं लिया गया है - man stripऔर आप एसी स्रोत संकलन मानने के -gलिए डिबग पीढ़ी उत्पन्न करते थे gcc), तो आप प्रतीक नामों द्वारा मुख्य सामग्रियों की जांच कर सकते हैं, जैसे कि यदि आपके पास एक चर / बफर था आपके स्रोत कोड में inputLine नाम , आप gdbउसकी सामग्री को देखने के लिए उस नाम का उपयोग कर सकते हैं । यानी gdbआपके प्रोग्राम्स के आरंभिक डेटा सेगमेंट की ऑफसेट से पता चल जाएगा जहां इनपुटलाइन शुरू होती है और उस वेरिएबल की लंबाई।

इसके अलावा पढ़ने Article1 , अनुच्छेद 2 , और जुओं से भरा हुआ किरकिरा के लिए निष्पादन योग्य और लिंकिंग स्वरूप (ELF) विनिर्देश


नीचे @mirabilos टिप्पणी के बाद अपडेट करें।

लेकिन अगर प्रतीक तालिका का उपयोग कर रहे हैं

$ gdb --batch -s a.out -c core -q -ex "x buf1"

का उत्पादन

 0x601060 <buf1>:    0x72617453

और फिर प्रतीक तालिका का उपयोग नहीं करना और सीधे पते की जांच करना,

$ gdb --batch -c core -q -ex "x 0x601060"

का उत्पादन

0x601060:   0x72617453

मैंने 2 डी कमांड में प्रतीक तालिका का उपयोग किए बिना सीधे मेमोरी की जांच की है।


मैं यह भी देखता हूं, @ user580082 का उत्तर स्पष्टीकरण के लिए आगे जोड़ता है, और वोट देगा।


6
"बेसिक स्टैक सेक्शन" के बारे में कभी नहीं सुना। .bss है (ऐतिहासिक) "ब्लॉक प्रतीक द्वारा शुरू किया" जबकि, और व्यावहारिक रूप से, "unitialized डेटा" .data और "डेटा प्रारंभ" है पाठ (नहीं .code) की दुकान मशीन कोड के लिए प्रयोग किया जाता है। बाइनरी में कोई स्टैक सेक्शन नहीं है, क्योंकि रन टाइम पर स्टैक बनाए जाते हैं।
जूलियाग्रे

"अगर आपको पता है कि सब कुछ तब था तो आप बस उसका उपयोग कर सकते हैं" या तो सच नहीं है क्योंकि कार्यक्रम में सब कुछ जरूरी नहीं कि पदचिह्न में शामिल हो।
mirabilos

1
@jlliagre आप सही हैं, मैंने गलती से .text कहा है .code (क्योंकि मैं उत्तर की रचना करते हुए एक स्पष्टीकरण सोच रहा था) - अद्यतन। मैंने गलती से नाम से गलत तरीके से bss के बारे में सोचा है, और अपने उत्तर को अपडेट किया है, लेकिन टालना शुरू किया * ब्लॉक सिंबल द्वारा शुरू किया क्योंकि मुझे नहीं लगता कि यह वास्तव में समीकरण में जोड़ता है, और समझाया है कि यह अन-इनिशियलाइज्ड डेटा के रूप में उपयोग किया जाता है, जो कि हमारा है सामान्य समझ। धन्यवाद - मैंने इस पोस्ट को सही करने के लिए आपकी टिप्पणी की सराहना की।
एक्स तियान

4

कोर फ़ाइल प्रक्रिया समाप्ति के समय स्टैक छवि, मेमोरी मैपिंग और रजिस्टरों का एक स्नैपशॉट है। जिसकी सामग्री को मैन मैन पेज में दिए अनुसार हेरफेर किया जा सकता है । डिफ़ॉल्ट निजी मैपिंग, साझा मैपिंग और ईएलएफ हेडर सूचनाओं को कोर फाइल में डंप कर दिया जाता है।

आपके सवाल पर आते हैं , कि gdb को निष्पादन योग्य बनाने की आवश्यकता है, क्योंकि यह निष्पादन को अनुकरण नहीं करता है, वैलग्राइंड जैसे द्विआधारी निर्देशों को पढ़ने और व्याख्या करने के बजाय यह प्रक्रिया का जनक बन जाता है ताकि चलाने के दौरान प्रक्रिया के व्यवहार को नियंत्रित किया जा सके। समय। यह क्रैश के दौरान मेमोरी मैपिंग और प्रोसेस की प्रोसेसर स्थिति को निर्धारित करने के लिए कोर फ़ाइल का उपयोग करता है।

लिनक्स अभिभावक प्रक्रियाओं में अपने बच्चों के बारे में अतिरिक्त जानकारी प्राप्त कर सकते हैं, विशेष रूप से उन्हें पेल्रेस करने की क्षमता जो डिबगर को प्रक्रिया की निम्न स्तर की जानकारी तक पहुँचने की अनुमति देती है जैसे कि इसकी मेमोरी को पढ़ना / लिखना, रजिस्टर करना, सिग्नल मैपिंग बदलना, इसका निष्पादन रोकना आदि।

जब आप कोई भी डिबगर काम करते हैं, तो आप एक बार कोर फाइल करने के निष्पादन योग्य प्रेरणा की आवश्यकता को समझेंगे।


1

(अन्य अच्छे उत्तरों के अलावा)

आधुनिक लिनक्स (और कई यूनिक्स जैसी) प्रणालियों पर, डिबगिंग जानकारी (प्रतीक के प्रकार, स्रोत कोड स्थान, चर के प्रकार, आदि आदि के बारे में मेटा-डेटा सहित) .... DWARF प्रारूप में है और ईएलएफ निष्पादन योग्य के अंदर बैठता है ( या ईएलएफ साझा पुस्तकालयों) जब यह किसी -gविकल्प के साथ संकलित किया जाता है। मैं संकलन कार्यक्रमों के साथ डिबग किए जाने की सलाह देते हैं -g3 -O0और शायद -fno-inlineहाल ही में एक का उपयोग कर यदि जीसीसी ; हालाँकि, जीसीसी के साथ आप अनुकूलन और डिबगिंग जानकारी दोनों के साथ भी संकलित कर सकते हैं, उदाहरण के लिए -O2 -g1, हालाँकि डिबग जानकारी उस मामले में थोड़ी "फजी" हो सकती है (यह कुछ शरारती हाइजेनबग्स को पकड़ने में थोड़ी मदद कर सकती है )।

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

BTW, GDB को किसी डिबग जानकारी के बिना निष्पादन योग्य के लिए कोर डंप को डीबग करने के लिए दर्दनाक रूप से उपयोग किया जा सकता है । लेकिन फिर आप मशीन कोड स्तर पर व्यावहारिक रूप से डिबग करते हैं (न कि प्रोग्रामिंग भाषाओं और उनके संकलक द्वारा प्रदत्त प्रतीकात्मक स्तर पर)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.