2012-04-27 11 views
20

डिबग किए बिना अवैध निर्देश त्रुटि उत्पन्न की है, एक प्रोग्राम चलाते समय मैंने असेंबली में लिखा है, मुझे Illegal instruction त्रुटि मिलती है। क्या यह जानने का कोई तरीका है कि कौन सा निर्देश त्रुटि उत्पन्न कर रहा है, बिना डीबगिंग के, क्योंकि जिस मशीन पर मैं चल रहा हूं उसके पास डीबगर या कोई विकास प्रणाली नहीं है। दूसरे शब्दों में, मैं एक मशीन में संकलित करता हूं और दूसरे पर चलता हूं। मैं अपने प्रोग्राम को उस मशीन पर परीक्षण नहीं कर सकता जिसे मैं संकलित कर रहा हूं क्योंकि वे एसएसई 4.2 का समर्थन नहीं करते हैं। जिस मशीन पर मैं प्रोग्राम चला रहा हूं वह फिर भी एसएसई 4.2 निर्देशों का समर्थन करता है।खोजें कि कौन से असेंबली निर्देश ने

मुझे लगता है कि ऐसा इसलिए हो सकता है क्योंकि मुझे एसएसई 4.2 निर्देशों को पहचानने के लिए असेंबलर (वाईएएसएम) को बताना होगा, जैसे कि हम इसे -msse4.2 ध्वज पास करके जीसीसी के साथ करते हैं। या क्या आपको लगता है कि इसका कारण नहीं है? एसएसई 4.2 निर्देशों को पहचानने के लिए वाईएएसएम को कैसे बताना है?

शायद मुझे SIGILL सिग्नल को फंसाना चाहिए और फिर SA_SIGINFO को डीकोड करना है यह देखने के लिए कि प्रोग्राम किस प्रकार का अवैध संचालन करता है।

+1

वाईएएसएम एसएसई 4.2 निर्देशों को पहचानता है, इसलिए यह समस्या नहीं है। क्या आप वाकई एसएसई 4.2 का समर्थन करते हैं? यह वास्तव में हार्डवेयर क्या है? आप प्रोग्राम को एक एमुलेटर में चला सकते हैं, वालग्रींड (जो एसएसई 4.2 के सबसेट का समर्थन करता है जिसका उपयोग ग्लिब और जीसीसी में किया जाता है) शायद काम करेगा। – hirschhornsalz

उत्तर

27

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

3

अच्छा ... आप निश्चित रूप से ट्रेस प्रिंटआउट सम्मिलित कर सकते हैं, ताकि आप जल्दी से कोड के बड़े क्षेत्रों को रद्द कर सकें। एक बार ऐसा करने के बाद, उदा।

$ objdump --disassemble my-crashing-program | less 

फिर उदा। जो फ़ंक्शन आप जानते हैं वह त्रुटि उत्पन्न कर रहा है, और कोड को पढ़ता है, जो अजीब दिखने वाली किसी चीज़ की तलाश में है।

मुझे पूरा यकीन नहीं है कि objdump अवैध निर्देश प्रदर्शित करता है, लेकिन उन्हें खड़ा होना चाहिए।

4

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

तो फिर तुम आप कितनी दूर पाने देखेंगे ...

(btw, एक अच्छा संपादक और कोडांतरक के मैक्रो वाक्य रचना की अच्छी समझ lifesavers जब मशीन कोड लिखने कर रहे हैं।)

+0

मुझे संदेह है कि असेंबलर को मुझे स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है कि मैं एसएसई 4.2 निर्देश का उपयोग कर रहा हूं, जैसे जीसीसी को -msse4.2 ध्वज पास करने की आवश्यकता है। – pythonic

+2

लेकिन असेंबलर में निर्देश सक्षम करने से बस अनुमत वाक्यविन्यास बदल जाता है। फँसाने और फँसाने के बीच यह अंतर नहीं होगा, मुझे कल्पना है। – DigitalRoss

+0

@ user1018562 नहीं। यदि असेंबलर को लक्ष्य आर्किटेक्चर के लिए अनुदेश की अनुमति नहीं मिलती है, तो यह त्रुटि होगी - लेकिन केवल संकलन समय के दौरान। यदि रनटाइम पर कोई त्रुटि मौजूद है, लेकिन संकलन समय के दौरान नहीं, तो विपरीत सत्य है - असेंबलर निर्देशों को उत्सर्जित करता है, जिसे लक्ष्य आर्किटेक्चर समझ में नहीं आता है। तो अगर कुछ भी है, तो आपको एसएसई निर्देशों को उत्सर्जित करने के लिए संकलक को बताना होगा। – hirschhornsalz

11

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

ulimit -c unlimited 
  • छद्म फ़ाइलों को कैसे कोर फ़ाइल नाम दिया जाएगा पर नियंत्रण (बिल्ली इन वर्तमान कॉन्फ़िगरेशन को देखने के लिए, बदलने के लिए उन्हें लिख:

    • कोर सक्षम करने के लिए लक्ष्य पर उदासीनता विन्यास):

      /proc/sys/kernel/core_pattern 
      /proc/sys/kernel/core_uses_pid 
      

    अपने सिस्टम पर, एक बार कोर डंप सक्षम होते हैं, एक क्रैश होने कार्यक्रम रिट होगा ई काम करने वाली निर्देशिका में बस "कोर" नाम की एक फ़ाइल।यह संभवतः आपके उद्देश्यों के लिए पर्याप्त है, लेकिन कोर डंप फ़ाइल का नाम बदलने के तरीके को बदलने से आप कोर डंप का इतिहास बना सकते हैं यदि यह आवश्यक हो (शायद अधिक अड़चन समस्या के लिए)।

  • +0

    लिनक्स बॉक्स मैंने 'ड्रॉप। $ पीआईडी' नामक सभी ड्रॉप कोर का उपयोग किया है। –

    +0

    @ वॉरेन: मेरा उबंटू बॉक्स (और हमारे द्वारा एम्बेडेड बिल्डिंग) किसी फ़ाइल के लिए डिफ़ॉल्ट रूप से 'कोर' नामक फ़ाइल में डिफ़ॉल्ट है। –

    15

    हाल ही में मुझे 132 निकास स्थिति कोड (128 + 4: प्रोग्राम सिग्नल द्वारा बाधित प्रोग्राम + अवैध निर्देश सिग्नल) के कारण दुर्घटना का सामना करना पड़ा। यहां बताया गया है कि मुझे पता चला कि कौन सी निर्देश दुर्घटना का कारण बन रहा था।

    पहले, मैं सक्षम कोर उदासीनता:

    $ ulimit -c unlimited 
    

    दिलचस्प बात यह है जहाँ मैं द्विआधारी चल रहा था से फ़ोल्डर core नाम का एक फ़ोल्डर निहित। मैं कोर डंप करने के लिए पीआईडी ​​जोड़ने के लिए लिनक्स बताने के लिए था:

    $ sudo sysctl -w kernel.core_uses_pid=1 
    

    तब मैं अपने कार्यक्रम चलाने के लिए और core.23650 नाम के एक कोर मिला है। मैंने जीडीबी के साथ बाइनरी और कोर लोड किया।

    Program terminated with signal SIGILL, Illegal instruction. 
    #0 0x00007f58e9efd019 in ??() 
    

    मेरा कार्यक्रम दुर्घटनाग्रस्त हो इसका मतलब है कि 0x00007f58e9efd019 पता स्मृति में एक अवैध अनुदेश के कारण:

    $ gdb program core.23650 
    

    एक बार मैं gdb में मिल गया, यह निम्न जानकारी से पता चला है। तब मैं एएसएम लेआउट में स्विच पिछले अनुदेश निष्पादित जाँच करने के लिए:

    (gdb) layout asm 
    >|0x7f58e9efd019 vpmaskmovd (%r8),%ymm15,%ymm0 
    |0x7f58e9efd01e vpmaskmovd %ymm0,%ymm15,(%rdi) 
    |0x7f58e9efd023 add $0x4,%rdi 
    |0x7f58e9efd027 add $0x0,%rdi 
    

    यह अनुदेश vpmaskmovd कि त्रुटि के कारण था। जाहिर है, मैं एक ऐसे सिस्टम पर AVX2 आर्किटेक्चर के उद्देश्य से एक प्रोग्राम चलाने की कोशिश कर रहा था जिसमें AVX2 निर्देश सेट के लिए समर्थन नहीं है।

    $ cat /proc/cpuinfo | grep avx2 
    

    आखिरकार, मैंने vpmaskmovd is an AVX2 only instruction की पुष्टि की।

    +0

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

    +0

    मैं जोड़ता हूं, यदि यह आपका प्रोग्राम है जो क्रैश हो जाता है, – ComputerSaysNo

    +1

    से ऊपर दिए गए चरणों का पालन करने से पहले '-ggdb' के साथ निर्मित किया गया था, तो मेरे एसएसई 2-केवल वीएम पर PMADDUBSW का उपयोग करने का प्रयास करने वाले प्रोग्राम के साथ ऐसी ही समस्या थी, धन्यवाद :) – Joril

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