निर्दिष्ट निष्पादन योग्य कारणों के बाहर सिंगल-स्टेप असेंबली कोड के लिए gdb का उपयोग करना त्रुटि "वर्तमान फ़ंक्शन की सीमा नहीं पा सकता है"


86

मैं gdb के लक्ष्य निष्पादन योग्य हूं और मेरे पास एक स्टैक भी नहीं है जो उस लक्ष्य से मेल खाता हो। मैं वैसे भी एकल-चरण करना चाहता हूं, ताकि मैं यह सत्यापित कर सकूं कि मेरे विधानसभा कोड में क्या हो रहा है, क्योंकि मैं x86 विधानसभा का विशेषज्ञ नहीं हूं। दुर्भाग्य से, जीडीबी इस सरल विधानसभा-स्तरीय डिबगिंग को करने से इनकार करता है। यह मुझे उचित ब्रेकपॉइंट पर सेट करने और रोकने की अनुमति देता है, लेकिन जैसे ही मैं एकल-चरण के लिए प्रयास करता हूं, जीडीबी त्रुटि "वर्तमान फ़ंक्शन की सीमा नहीं पा सकता है" और ईआईपी नहीं बदलता है।

अतिरिक्त जानकारिया:

मशीन कोड gcc asm स्टेटमेंट द्वारा जनरेट किया गया था और मैंने इसे कर्नेल मेमोरी लोकेशन पर कॉपी किया था जहाँ यह निष्पादित हो रहा है, objdump -d के आउटपुट से। मैं लोड ऑब्जेक्ट का उपयोग करने के लिए एक साधारण तरीके से अपने ऑब्जेक्ट कोड को स्थानांतरित पते पर लोड करने के लिए बुरा नहीं मानूंगा, लेकिन यह ध्यान रखें कि लोडिंग को कर्नेल मॉड्यूल में किया जाना है।

मुझे लगता है कि एक और विकल्प एक नकली कर्नेल मॉड्यूल या डिबग जानकारी फ़ाइल को gdb को देने के लिए होगा, जिससे यह विश्वास हो सके कि यह क्षेत्र प्रोग्राम कोड के भीतर है। जीडीबी कर्नेल निष्पादन योग्य पर ही ठीक काम करता है।

(जो लोग वास्तव में जानना चाहते हैं, मैं एक VMware VM के अंदर लिनक्स कर्नेल डेटा स्पेस में रनटाइम पर कोड डाल रहा हूं और इसे gdb रिमोट डीबगिंग से VMD वर्कस्टेशन के बिल्ट-इन gdb स्टब के माध्यम से डीबग कर रहा हूं। नोट कर्नेल नहीं लिख रहा है। शोषण करता है; मैं एक सुरक्षा स्नातक छात्र हूं जो एक प्रोटोटाइप लिख रहा है।)

(मैं अपने विधानसभा के अंदर प्रत्येक निर्देश पर एक ब्रेकपॉइंट सेट कर सकता हूं। यह काम करता है लेकिन थोड़ी देर बाद काफी श्रमसाध्य हो जाएगा, क्योंकि x86 विधानसभा निर्देशों का आकार बदलता रहता है और हर बार जब मैं रिबूट होता हूं तो विधानसभा का स्थान बदल जाएगा।)


चतुर ksplice.com लोग "नकली" कर्नेल मॉड्यूल को इकट्ठा करके और उन्हें लोड करके कर्नेल में डेटा और कोड इंजेक्ट करते हैं। और अगर वे ऐसा कर सकते हैं, तो आप क्यों नहीं कर सकते? ;-)
अल्पकालिक

जवाबों:


116

आप उपयोग कर सकते हैं stepiया nexti(जो को संक्षिप्त किया जा सकता है siया niआपकी मशीन कोड के माध्यम से कदम के लिए)।


1
वाह। रेट्रोस्पेक्ट में मुझे नहीं पता कि मैं स्टैपी के बारे में कैसे भूल गया। मुझे लगता है कि मैं सिर्फ इसलिए मान गया क्योंकि gdb के पास स्रोत कोड नहीं था जो कि कदम विधानसभा निर्देशों को वापस कर देगा।
पॉल

1
नोट: आप अक्सर असेंबली प्रोग्राम के लिए "ब्रेक मेन", "रन" टाइप नहीं कर सकते हैं। इसके बजाय "लेआउट asm", "start" टाइप करें। मुझे यह संदेश नीचे पढ़ने से मिला, लेकिन इस पोस्ट को पढ़ने वाला कोई और रोगी नहीं हो सकता है।
दिमित्री

1
@Dmitry startके बराबर है tbreak main, जिसके बाद run(ध्यान दें: tbreakके बजाय break)
रुस्लान

151

इसके बजाय gdb, भागो gdbtui। या स्विच के gdbसाथ चलाएं -tui। या C-x C-aदर्ज करने के बाद दबाएं gdb। अब आप GDB के TUI मोड में हैं।

layout asmऊपरी विंडो डिस्प्ले असेंबली बनाने के लिए दर्ज करें - यह स्वचालित रूप से आपके इंस्ट्रक्शन पॉइंटर का अनुसरण करेगा, हालांकि आप डिबगिंग करते समय फ़्रेम या स्क्रॉल भी बदल सकते हैं। C-x sSingleKey मोड में प्रवेश करने के लिए दबाएँ , जहाँ run continue up down finishआदि को एक ही कुंजी से संक्षिप्त किया जाता है, जिससे आप अपने प्रोग्राम को बहुत तेज़ी से चला सकते हैं।

   + ------------------------------------------------- -------------------------- +
B +> | 0x402670 <main> पुश% r15 |
   | 0x402672 <main + 2> mov% edi,% r15d |
   | 0x402675 <main + 5> पुश% r14 |
   | 0x402677 <main + 7> पुश% r13 |
   | 0x402679 <main + 9> mov% rsi,% r13 |
   | 0x40267c <main + 12> पुश% r12 |
   | 0x40267e <main + 14> पुश% rbp |
   | 0x40267f <main + 15> पुश% rbx |
   | 0x402680 <main + 16> उप $ 0x438,% rsp |
   | 0x402687 <main + 23> mov (% rsi),% rdi |
   | 0x40268a <main + 26> movq $ 0x402a10,0x400 (% rsp) |
   | 0x402696 <main + 38> movq $ 0x0,0x408 (% rsp) |
   | 0x4026a2 <main + 50> movq $ 0x402510,0x410 (% rsp)
   + ------------------------------------------------- -------------------------- +
चाइल्ड प्रोसेस 21518 इन: मेन लाइन: ?? पीसी: 0x402670
(gdb) फ़ाइल / ऑप्ट / j64-602 / bin / jconsole
/Opt/j64-602/bin/jconsole...done से प्रतीकों को पढ़ना।
(कोई डिबगिंग प्रतीक नहीं मिला) ... किया।
(gdb) लेआउट asm
(gdb) प्रारंभ
(Gdb)

26

आर सैमुअल क्लैचको के जवाब में पहले से ही सुझाए गए display/i $pcउपयोग से पहले आप यहां सबसे उपयोगी चीज कर सकते हैं stepi। यह बताता है कि gdb प्रत्येक बार प्रॉम्प्ट को छापने से पहले वर्तमान निर्देश को अलग कर देता है; तब आप stepiकमांड को दोहराने के लिए एंटर दबाए रख सकते हैं ।

( अधिक विस्तार के लिए किसी अन्य प्रश्न का मेरा उत्तर देखें - उस प्रश्न का संदर्भ अलग था, लेकिन सिद्धांत एक ही है।)

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