2011-12-08 16 views
5

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

अगर मैं ग्राहक में प्रतीकों लोड करने के लिए फ़ाइल आदेश का उपयोग करने की कोशिश मैं:

reading symbols from <path>/libQtWebKit.so.4.7.2...(no debugging symbols found)...done. 

और फिर, जब दुर्घटना होती है:

Program received signal SIGSEGV, Segmentation fault. 
0x00000000 in ??() 
(gdb) bt 
#0 0x00000000 in ??() 
#1 0x4bf38b88 in ??() 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 

मेरे पुस्तकालयों रिलीज में संकलित किया गया है लेकिन प्रतीकों वास्तव में वहाँ हैं। एनएम के साथ मैं उनको पा सकता हूं। मुझे केवल प्रश्न चिह्न क्यों मिलते हैं? क्या यह केवल इसलिए है क्योंकि पुस्तकालयों को अनुकूलन के साथ संकलित किया गया है? रिलीज मोड में पुस्तकालयों के साथ डीबग करना संभव नहीं है?

उत्तर

2

corrupt stack नोट शायद आपकी समस्या है। यह एक रिटर्न पता या आभासी तालिका प्रविष्टि की तरह दिखता है या कुछ शून्य के साथ अधिलेखित किया गया था, और उसके बाद नियंत्रण स्थानांतरित किया गया था। यहां तक ​​कि यदि आपके पास प्रतीकों उपलब्ध हैं, तो वे पते वैध प्रतीकों को इंगित नहीं कर रहे हैं। इसलिए segfault।

मैं आपके काम को ईर्ष्या नहीं देता हूं। ट्रैक करने के लिए ये सबसे कठिन बग हैं, और जब आप कोड को बदलने और पकड़ने के लिए कोड बदलते हैं तो भी स्थानांतरित या अस्थायी रूप से दूर जा सकते हैं। आपकी सबसे अच्छी शर्त आमतौर पर git bisect या आपके वीसीएस समकक्ष की तरह कुछ प्रतिबद्धता खोजने के बराबर होती है। उम्मीद है कि पुनरुत्पादन करना बहुत मुश्किल नहीं है।

+1

दुर्भाग्यवश यह वेबकिट का एक संशोधन है। वापस करने के लिए कोई पिछला संस्करण नहीं है। डीबग करने का कोई और तरीका? शायद valgrind? –

1

एक चाल जिसे आप कभी-कभी "पता 0 पर एसईजीवी" प्राप्त करते हैं, तब समस्या का उपयोग पीसी में ढेर के शीर्ष से वापसी पते को मैन्युअल रूप से पॉप करने और वहां से एक स्टैक ट्रेस करने की कोशिश कर रहा है। यह मानता है कि आपको एक न्यूल पॉइंटर के माध्यम से अप्रत्यक्ष कॉल करके 0 को संबोधित करना है, जो 0

अब मैं एआरएम से बहुत परिचित नहीं हूं, लेकिन एक x86 पीसी पर, आप करेंगे:

(gdb) set $eip = *(void **)$esp 
(gdb) set $esp = $esp + 4 

और फिर यह पता लगाने के लिए एक और बैकट्रैक करें कि आप वास्तव में कहां हैं।

यदि आप अपने कंपाइलर द्वारा एआरएम के लिए उपयोग किए जाने वाले कॉलिंग सम्मेलन को समझ सकते हैं, तो आपको कुछ ऐसा करने में सक्षम होना चाहिए।

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