दूसरा भाग आसानी से समझाया गया है (जैसे फ़्लोरिफाइड सही ढंग से बताया गया है): जीडीबी मूल मेमोरी सामग्री दिखाता है, ब्रेकपॉइंट "बाइट्स" नहीं। डिफॉल्ट मोड में यह वास्तव में ब्रेकपॉइंट्स को हटा देता है जब डीबगर निलंबित हो जाता है और जारी रखने से पहले उन्हें फिर से सम्मिलित करता है। उपयोगकर्ता आमतौर पर ब्रेकपॉइंट्स के लिए उपयोग किए जाने वाले अजीब संशोधित निर्देशों को नहीं देखते हैं।
आपके सी कोड के साथ आप कुछ बाइट्स के लिए ब्रेकपॉइंट चूक गए। जीडीबी function prologue के बाद ब्रेकपॉइंट सेट करता है, क्योंकि फ़ंक्शन प्रस्तावना आम तौर पर जीडीबी उपयोगकर्ता नहीं देखना चाहते हैं।इसलिए, यदि आप foo को तोड़ते हैं, तो वास्तविक ब्रेकपॉइंट आमतौर पर उसके बाद कुछ बाइट्स स्थित होगा (प्रस्तावना कोड पर निर्भर करता है जो फ़ंक्शन पर निर्भर करता है क्योंकि यह स्टैक पॉइंटर, फ्रेम पॉइंटर और अन्य को सहेजने की आवश्यकता नहीं हो सकती है)। लेकिन यह जांचना आसान है।
#include <stdio.h>
int main()
{
int i,j;
unsigned char *p = (unsigned char*)main;
for (j=0; j<4; j++) {
printf("%p: ",p);
for (i=0; i<16; i++)
printf("%.2x ", *p++);
printf("\n");
}
return 0;
}
हम अपने आप में इस कार्यक्रम चलाते हैं यह प्रिंट:
0x40057d: 55 48 89 e5 48 83 ec 10 48 c7 45 f8 7d 05 40 00
0x40058d: c7 45 f4 00 00 00 00 eb 5a 48 8b 45 f8 48 89 c6
0x40059d: bf 84 06 40 00 b8 00 00 00 00 e8 b4 fe ff ff c7
0x4005ad: 45 f0 00 00 00 00 eb 27 48 8b 45 f8 48 8d 50 01
अब हम gdb में इसे चलाने (अतः के लिए उत्पादन फिर से प्रारूपित) मैं इस कोड का इस्तेमाल किया।
(gdb) break main
Breakpoint 1 at 0x400585: file ../bp.c, line 6.
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400585 in main at ../bp.c:6
(gdb) disas/r main,+32
Dump of assembler code from 0x40057d to 0x40059d:
0x000000000040057d (main+0): 55 push %rbp
0x000000000040057e (main+1): 48 89 e5 mov %rsp,%rbp
0x0000000000400581 (main+4): 48 83 ec 10 sub $0x10,%rsp
0x0000000000400585 (main+8): 48 c7 45 f8 7d 05 40 00 movq $0x40057d,-0x8(%rbp)
0x000000000040058d (main+16): c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp)
0x0000000000400594 (main+23): eb 5a jmp 0x4005f0
0x0000000000400596 (main+25): 48 8b 45 f8 mov -0x8(%rbp),%rax
0x000000000040059a (main+29): 48 89 c6 mov %rax,%rsi
End of assembler dump.
इस हम सत्यापित के साथ
, कि इस कार्यक्रम सही बाइट्स प्रिंट कर रहा है। लेकिन यह भी दिखाता है कि 0x400585 (जो फ़ंक्शन प्रस्तावना के बाद है) पर ब्रेकपॉइंट डाला गया है, फ़ंक्शन के पहले निर्देश पर नहीं। अब हम (रन) के साथ gdb के तहत कार्यक्रम चलाने के लिए और फिर "जारी रखें" के बाद ब्रेकप्वाइंट मारा जाता है, तो हम इस उत्पादन प्राप्त करें:
(gdb) cont
Continuing.
0x40057d: 55 48 89 e5 48 83 ec 10 cc c7 45 f8 7d 05 40 00
0x40058d: c7 45 f4 00 00 00 00 eb 5a 48 8b 45 f8 48 89 c6
0x40059d: bf 84 06 40 00 b8 00 00 00 00 e8 b4 fe ff ff c7
0x4005ad: 45 f0 00 00 00 00 eb 27 48 8b 45 f8 48 8d 50 01
यह अब 0xcc से पता चलता पते 9 मुख्य में बाइट्स के लिए मुद्रित किया जा रहा ।
इस विषय पर एक दिलचस्प लेख है 'डीबगर कैसे काम करता है', लेख 'आईएनटी 3 के पीछे जादू' के इस भाग पर एक नज़र डालें: http://www.alexonlinux.com/how-debugger-works # the_magic_behind_int_3 –