2015-11-11 4 views
11

मैं अपने कार्यक्रम में असफल आक्रमणों को पकड़ने का प्रयास कर रहा हूं। मैं एक लाइब्रेरी का उपयोग कर रहा हूं जो एक कस्टम फ़ंक्शन या मैक्रो के बजाय() को प्रत्यक्ष कॉल करता है, और यह इस लाइब्रेरी के भीतर है, मैं वर्तमान में कई पोर्टिंग-संबंधित बग का पता लगाने की कोशिश कर रहा हूं। शामिल सब कुछ g ++ में डीबग प्रतीकों के साथ संकलित किया गया है।जीडीबी में असफल आक्रमणों को तोड़ने का सही तरीका क्या है?

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

मैं कैसे किसी भी पर तोड़ सकते हैं ज़ोर इस तरह से कि ज़ोर कॉल के दायरे के भीतर callstack और चर की परीक्षा की अनुमति देता है में gdb & जीसीसी का उपयोग कर में विफल रहा है?

यह बेहतर होगा अगर समाधान ने मुझे जोर की विफलता को त्यागने और चलना जारी रखा।

+0

विजुअल स्टूडियो में विंडोज़ पर, ब्रेकिंग असफल 'जोर' का डिफ़ॉल्ट व्यवहार है। मुझे हैरान है कि * निक्स दुनिया में मामला नहीं है - आम तौर पर असफल 'जोर' क्या करता है? – Angew

+4

प्रोग्राम चलाने से पहले, gdb में, आप फ़ंक्शन abort() पर ब्रेकपॉइंट जोड़ने के लिए 'ब्रेक अपोर्ट' (या बस 'बी abort') का उपयोग कर सकते हैं। इससे कम से कम एक बैकट्रैक बनने देगा जब कोई दावा विफल हो जाता है (माना जाता है कि यह 'abort()' कहता है, जब कुछ करता है; कुछ कार्यान्वयन इसके बजाय 'बाहर निकलें()' कह सकते हैं)। हालांकि निरंतर निष्पादन के बारे में निश्चित नहीं है। – notmyfriend

+2

आम तौर पर यह डिफ़ॉल्ट रूप से काम करता है, जैसा कि जोर() कॉल निरस्त करता है, और निरंतर उस सिग्नल पर डिफॉल्ट ब्रेक द्वारा SIGABRT सिग्नल और जीडीबी बढ़ाता है, जिससे आप स्टैक का निरीक्षण कर सकते हैं, स्टैक को ऊपर/नीचे ले जा सकते हैं। आपके फ़ंक्शन में जोर() और चर का निरीक्षण करें और इसी तरह। – nos

उत्तर

11

abort() पर ब्रेकपॉइंट सेट करना सबसे अच्छा जवाब प्रतीत होता है।

break abort जीडीबी के सीएलआई में।

+0

मूल पोस्टर और @ नोटमीफ्रेंड दोनों ने अपनी टिप्पणियों में उत्तर पोस्ट किए, लेकिन किसी को आधिकारिक उत्तर लिखने का सुझाव देने के बाद, और जब भी मैं भूल गया, इस पृष्ठ पर वापस आने के बाद, और फिर यह जानने के लिए सभी टिप्पणियों को दोबारा पढ़ना पड़ा यह था, मैं बस इसे लिख रहा हूँ! –

+2

यह प्रतिभा है! – Antonio

3

नहीं break की जरूरत है, बस शीघ्र

abort() पर bt टाइप का कारण बनता है एक संकेत उठाया जा, और gdb पहले से ही डिफ़ॉल्ट रूप से संकेतों पर टूट जाता है।

उदा .:

#include <assert.h> 

void g(int i) { 
    assert(0); 
} 

void f(int i) { 
    g(i); 
} 

int main(void) { 
    f(1); 
} 
फिर

:

gcc -std=c99 -O0 -ggdb3 -o a a.c 
gdb -ex run ./a 

तो बस टाइप bt खोल में:

(gdb) bt 
#0 __GI_raise ([email protected]=6) at ../sysdeps/unix/sysv/linux/raise.c:58 
#1 0x00007ffff7a483ea in __GI_abort() at abort.c:89 
#2 0x00007ffff7a3ebb7 in __assert_fail_base (fmt=<optimized out>, [email protected]=0x555555554788 "0", [email protected]=0x555555554784 "a.c", [email protected]=4, 
    function=fu[email protected]=0x55555555478a <__PRETTY_FUNCTION__.1772> "g") at assert.c:92 
#3 0x00007ffff7a3ec62 in __GI___assert_fail (assertion=0x555555554788 "0", file=0x555555554784 "a.c", line=4, function=0x55555555478a <__PRETTY_FUNCTION__.1772> "g") 
    at assert.c:101 
#4 0x00005555555546ca in g (i=1) at a.c:4 
#5 0x00005555555546df in f (i=1) at a.c:8 
#6 0x00005555555546f0 in main() at a.c:12 

कौन सा पहले से ही समारोह मान दिखाता है (f (i=1))।

और तुम भी हमेशा की तरह कर सकते हैं:

(gdb) f 4 
#4 0x00005555555546ca in g (i=1) at a.c:4 
4   assert(0); 
(gdb) p i 
$1 = 1 

उबंटू 16.10 में परीक्षण किया गया, 7.11 GDB।

0

यदि ऊपर दिए गए उत्तरों का सुझाव आपके लिए काम नहीं करता है, तो आप __assert_fail फ़ंक्शन को तोड़ने का प्रयास कर सकते हैं।

break __assert_fail 

नाम संभवत: कार्यान्वयन है - निर्भर है, लेकिन यह अगर आप अपने मंच पर ज़ोर मैक्रो की परिभाषा को देखने को खोजने के लिए आसान है। यह आपको SIGABRT से पहले तोड़ने की अनुमति देगा।

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