लिनक्स पर जीडीबी के लिए सी या सी ++ कोड में ब्रेकपॉइंट सेट करें


105

मैं प्रोग्रामेटिक रूप से C या C ++ कोड में एक ब्रेकपॉइंट कैसे सेट कर सकता हूं जो लिनक्स पर gdb के लिए काम करेगा?

अर्थात:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

8
बहुत अधिक साइड नोट (नाइटपिक के लिए खेद है), लेकिन यदि आप पोर्टेबिलिटी के बारे में चिंतित हैं तो आप शायद शुद्धता के बारे में भी चिंतित हैं - इसलिए int mainइसके बजाय void main
स्टुअर्ट गोलोडेटेज़

@ स्टुअर्ट - फिक्स्ड। कुछ समय पहले ऐसा करना चाहिए था।
जे। पोलर

4
@ जे। गोल्फर: यह return 0आवश्यक नहीं है, हालांकि, और सिर्फ शोर है!
ऑर्बिट

जवाबों:


107

एक तरीका एक रुकावट को इंगित करना है:

#include <csignal>

// Generate an interrupt
std::raise(SIGINT);

सी में:

#include <signal.h>
raise(SIGINT);

अद्यतन : MSDN बताता है कि Windows वास्तव में समर्थन नहीं करता है SIGINT, इसलिए यदि पोर्टेबिलिटी एक चिंता का विषय है, तो आप शायद उपयोग करना बेहतर है SIGABRT


हां, यह ऑपरेटिंग सिस्टम / कंपाइलर / डीबगर्स पर काम करना चाहिए।
होवार्ड एस

1
मैं अन्य डिबगर्स को नहीं जानता, लेकिन जीडीबी सिग्नल हैंडलिंग के बारे में बहुत लचीला है ।
कैसकबेल

4
हमने कुछ यूनियनों पर SIGTRAP को बेहतर पाया
JBRWilkinson

1
विंडोज, MSVC में आप __debug_break, DebugBreak या _asm {int 3} का उपयोग कर सकते हैं।
फर्नांडो गोंजालेज सांचेज़

2
@FernandoGonzalezSanchez: वास्तव में फ़ंक्शन नाम है __debugbreak()और नहीं __debug_break() , जैसा कि आप यहाँ
Morix Dev

27

जिस परियोजना में मैं काम करता हूं, उसमें हम यह करते हैं:

raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */

(हमारे मामले में अगर हम डिबगर के बाहर हुआ था, तो यह मुश्किल से क्रैश करना चाहता था, यदि संभव हो तो एक क्रैश रिपोर्ट उत्पन्न करता है। यही एक कारण है कि हमने SIGABRT का उपयोग किया है। विंडोज, मैक और लिनक्स में इस तरह से कुछ करने के बाद हमने कई प्रयास किए। #ifdefs, ने यहाँ टिप्पणी की: http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 ।)


2
हमेशा की तरह खिड़कियां दूसरों की तरह नहीं
लगतीं

क्या कार्यक्रम को जारी स्थिति में जारी रखने के लिए "सिग्नल 0" जारी करना संभव है? इस बिंदु से 'n' या 's' का उपयोग करना अच्छा होगा, बिना 'c' जारी किए।
जेसन डौकेट

2
@JasonDoucette यदि आप वास्तव में केवल कार्यक्रम को रोकना चाहते हैं, तो आप breakpoint()अपने कार्यक्रम में एक फ़ंक्शन जोड़ना चाहते हैं (यह खाली हो सकता है या बस एक प्रिंट स्टेटमेंट हो सकता है) और break breakpointअपने में जोड़ें ~/.gdbinit
जेसन ऑरेंडोर्फ

26

यहाँ देख कर , मुझे निम्नलिखित तरीका मिला:

void main(int argc, char** argv)
{
    asm("int $3");
    int a = 3;
    a++;  //  In gdb> print a;  expect result to be 3
}

यह मेरे लिए एक टच हैडिश लगता है। और मुझे लगता है कि यह केवल x86 आर्किटेक्चर पर काम करता है।


3
और केवल AT & T असेंबली सिंटैक्स का समर्थन करने वाले कंपाइलरों के साथ। विशेष रूप से, Microsoft का कंपाइलर ( cl.exe) इस सिंटैक्स का समर्थन नहीं करता है, लेकिन एक अलग सिंटैक्स का उपयोग करता है।
होवार्ड एस

सवाल लिनक्स के बारे में था, इसलिए मुझे लगता है कि हम मान सकते हैं कि gcc सिंटैक्स x86 के लिए काम करेगा।
जे.एस.

BTW - मैंने अपनी x86 मशीन पर उपरोक्त कोशिश की और यह काम किया। मैं उत्सुक था अगर ऐसा करने का एक बेहतर तरीका था। लगता है जैसे है।
जे। पॉल्फर

2
मैं विंडोज़ पर मिंगव का उपयोग कर रहा हूं ताकि अन्य सुझाव मेरी मदद न कर सकें। SIGINT सिग्नल को उठाना केवल एप्लिकेशन को समाप्त करता है, SIGTRAP को मिंगव हेडर में परिभाषित नहीं किया जाता है ... वास्तव में निर्देश का उपयोग करके SIGTRAP और gdb को उचित रेखा पर अच्छी तरह से टूट जाता है।
मटका

लिनक्स में, int 3एक SIGTRAP को उठाता है।
सिरो सेंटिल्ली 郝海东 i iro i 法轮功 '18

12

__asm__("int $3"); कार्य करना चाहिए:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    __asm__("int $3");
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

1
मुझे यह पसंद है #define, ताकि मुझे वाक्य रचना याद न हो। मैंने इसे अपने पूरे कोड में छिड़का है, कभी-कभी इसके स्थान पर assert(), डिबगर को रोकने के बाद से मुझे सभी चर और स्टैक की जांच करनी चाहिए। और, ज़ाहिर है,
मुखर की

दिलचस्प है कि यह 10 अपवोट्स है जब "लिनक्स" और "जीडीबी" के प्रश्न बाधा उत्पन्न करते हैं, विधानसभा के लिए सहारा देने के बाहर बहुत सारे विकल्प देते हैं, जो हमेशा पोर्टेबिलिटी के लिए एक अंतिम उपाय होना चाहिए अगर कुछ और नहीं। कृपया कुछ अन्य उत्तर देखें।
बेंजामिन क्रॉफोर्ड Ctrl-Alt-Tut

5

सॉफ्टवेयर ब्रेकप्वाइंट के लिए समर्पित सिग्नल का उपयोग नहीं करने के लिए इतने सारे उत्तरों को देखने से निराश होना SIGTRAP:

#include <signal.h>

raise(SIGTRAP); // At the location of the BP.

1

ओएस एक्स पर आप बस कॉल कर सकते हैं std::abort()(यह लिनक्स पर भी ऐसा ही हो सकता है)


कौन सी लाइब्रेरी?
एलेक्स

यह मानक C ++ लाइब्रेरी का हिस्सा है और क्रॉस-प्लेटफ़ॉर्म है जहां C ++ 11-compliant कंपाइलर मौजूद हैं। हालांकि, यह SIGABRT को बढ़ाता है, जो वास्तव में इस उदाहरण को बढ़ाने के लिए एक उपयुक्त संकेत नहीं है।
बेंजामिन क्रॉफर्ड Ctrl-Alt-Tut-
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.