2011-03-17 21 views
25

मैं लिनक्स पर जीडीबी 7.1 में सी ++ डीबग कर रहा हूं।क्या कॉल स्टैक पर सशर्त जीडीबी में ब्रेकपॉइंट सेट करने का कोई तरीका है?

मेरे पास एक समारोह a() है जिसे कोड में कई स्थानों पर बुलाया जाता है। मैं इसमें ब्रेकपॉइंट सेट करना चाहता हूं, लेकिन केवल अगर इसे b() से बुलाया गया था। इसे करने का कोई तरीका है?

क्या ऐसा करने का कोई तरीका है अगर b()c() से और इसलिए विज्ञापन infinitum पर कहा गया था?

उत्तर

21

एन ईडी आप का वर्णन अक्सर होता है, आमतौर पर some_utility_fn के संदर्भ में बहुत कुछ कहा जाता है, लेकिन आप केवल some_other_fn से कॉल में रूचि रखते हैं।

आप शायद सीवीएस ट्रंक से जीडीबी में नए एम्बेडेड पायथन समर्थन का उपयोग करके इस संपूर्ण बातचीत को स्क्रिप्ट कर सकते हैं।

अजगर के बिना, आप आप क्या कर सकते में सीमित हैं, लेकिन हमेशा की तरह तकनीक a() पर एक विकलांग ब्रेकप्वाइंट है, और एक आदेश, b() पर एक ब्रेकपाइंट से जुड़ी से यह सुनिश्चित करना है।

int a(int x) 
{ 
    return x + 1; 
} 

int b() 
{ 
    return a(1); 
} 

int call_a_lots() 
{ 
    int i, sum = 0; 
    for (i = 0; i < 100; i++) 
    sum += a(i); 
} 

int main() 
{ 
    call_a_lots(); 
    return b(); 
} 

gcc -g t.c 
gdb -q ./a.out 
Reading symbols from /tmp/a.out...done. 
(gdb) break a 
Breakpoint 1 at 0x4004cb: file t.c, line 3. 
(gdb) disable 1 
(gdb) break b 
Breakpoint 2 at 0x4004d7: file t.c, line 8. 
(gdb) command 2 
>silent 
>enable 1 
>continue 
>end 
(gdb) run 

Breakpoint 1, a (x=1) at t.c:3 
3  return x + 1; 
(gdb) bt 
#0 a (x=1) at t.c:3 
#1 0x00000000004004e1 in b() at t.c:8 
#2 0x000000000040052c in main() at t.c:21 
(gdb) q 

देखा:

यहाँ एक उदाहरण है हम a()b() से कहा जाता है पर बंद कर दिया है, a() करने के लिए पिछले 100 कॉल की अनदेखी।

+1

'आदेश 2' क्या करता है? –

+3

@NathanFellman 'कमांड 2 '2 –

+0

को तोड़ने के लिए कमांड को जोड़ता है क्या यह पाइथन के बिना स्वचालित हो सकता है? http://stackoverflow.com/questions/41397560/how-to-pass-cli-arguments-to-a-commands-inside-a-define-in-gdb –

4

यह सुनिश्चित नहीं है कि जीडीबी द्वारा इसे कैसे किया जाए।
लेकिन आप की तरह वैश्विक चर घोषणा कर सकते हैं:

bool call_a = false; 

और जब गलत पर एक

call_a = true; 
a(); 

और सेट call_a बुला जब अन्य समारोह एक() या फोन अपने ब्रेकप्वाइंट

तो बाद ख कंडीशन ब्रेक-पॉइंट

break [line-number] if call_a == true 
7

मैं gdb 7.6 कि पहले से ही उपलब्ध है पर इस परीक्षण किया है, लेकिन यह gdb 7.2 पर काम नहीं करता है और शायद gdb 7.1 पर:

तो यह main.cpp है:

int a() 
{ 
    int p = 0; 
    p = p +1; 
    return p; 
} 

int b() 
{ 
    return a(); 
} 

int c() 
{ 
    return a(); 
} 

int main() 
{ 
    c(); 
    b(); 
    a(); 
    return 0; 
} 

फिर जी ++ - जी main.cpp

यह my_check.py है:

class MyBreakpoint (gdb.Breakpoint): 
    def stop (self): 
     if gdb.selected_frame().older().name()=="b": 
      gdb.execute("bt") 
      return True 
     else: 
      return False 

MyBreakpoint("a") 

और यह है कि यह कैसे काम करता है:

4>gdb -q -x my_check.py ./a.out 
Reading symbols from /home/a.out...done. 
Breakpoint 1 at 0x400540: file main.cpp, line 3. 
(gdb) r 
Starting program: /home/a.out 
#0 a() at main.cpp:3 
#1 0x0000000000400559 in b() at main.cpp:10 
#2 0x0000000000400574 in main() at main.cpp:21 

Breakpoint 1, a() at main.cpp:3 
3   int p = 0; 
(gdb) c 
Continuing. 
[Inferior 1 (process 16739) exited normally] 
(gdb) quit 
+0

हमें पाइथन फ़ंक्शन को 'ए' और ' सीएलआई तर्क के रूप में बी। –

+0

पर एक स्केच शुरू किया गया: https://github.com/cirosantilli/dotfiles/blob/15addf77a231b577ee419923c3236ed7c408f8eb/home/.gdbinit.py#L81 लेकिन आलसी हो गया। ध्यान दें कि शुद्ध पायथन में 'gdb.Breakpoint (अस्थायी = सही)' के साथ अस्थायी ब्रेकपॉइंट संभव है और यह स्टैक '.older()' श्रृंखला को हर तरह से बढ़ाना अच्छा होगा। –

0

बांह के लिए एक आसान एक है:

समारोह आप रुचि रखते हैं में ब्रेकपाइंट सेट करें।

break a 

कि ब्रेकप्वाइंट के लिए एक gdb आदेश देते हैं।

command 1 
up 1 
if $lr == 0x12345678 
    echo match \n 
    down 1 
else 
    echo no match \n 
    echo $lr \n 
    down 1 
    cont 
end 
end 

जब कभी आप समारोह एक() में आते हैं, तो आदेश अस्थायी तौर पर इस प्रकार लिंक रजिस्टर को अद्यतन करने के एक ढेर फ्रेम दिखाई नहीं देता। कॉलर्स लिंक रजिस्टर वैल्यू का तब उपयोग जारी रखा जा सकता है जब कॉलर निष्पादन पथ की आवश्यकता नहीं है।

आनंद लें।

4

पायथन स्क्रीप्टिंग की तुलना में एक आसान समाधान temporary breakpoint का उपयोग कर रहा है।

यह इस तरह दिखता है:

b ParentFunction 
command 1 
    tb FunctionImInterestedIn 
    c 
end 

हर बार जब आप ParentFunction में तोड़ने, तो आप एक बार की ब्रेकप्वाइंट समारोह पर सेट करेंगे आप वास्तव में रुचि रखते हैं, तो उनका प्रदर्शन जारी रहेगा (शायद जब तक आप हिट वह ब्रेकपॉइंट)।

जब से तुम ठीक एक बार FunctionImInterestedIn पर विभाजित करेंगे, यह अगर FunctionImInterestedInParentFunction के संदर्भ में कई बार कहा जाता है काम नहीं करेगा और आप प्रत्येक मंगलाचरण पर तोड़ने के लिए चाहते हैं।

+0

ऐसा लगता है कि आपकी अंतिम वाक्य काटा गया था। लिखने का मतलब क्या था? –

+0

क्या यह पाइथन के बिना स्वचालित हो सकता है? http://stackoverflow.com/questions/41397560/how-to-pass-cli-arguments-to-a-commands-inside-a-define-in-gdb –

0

gdb पाइथन के लिए बिना किसी आवश्यकता के सीधे इसे संभाल सकता है। बस यह करें:

b a if $_caller_is("b") 
संबंधित मुद्दे