GDB调试 曾经终败给现在 2022-03-29 17:38 503阅读 0赞 [https://www.cnblogs.com/HKUI/p/8955443.html][https_www.cnblogs.com_HKUI_p_8955443.html] GDB调试 启动程序准备调试 GDB yourpram 或者 先输入GDB 然后输入 file yourpram 然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传递给该程序 参数列表 <table> <tbody> <tr> <td style="vertical-align:top;"> <p>命令</p> </td> <td style="vertical-align:top;"> <p>命令缩写</p> </td> <td style="vertical-align:top;"> <p>命令说明</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>list</p> </td> <td style="vertical-align:top;"> <p>l</p> </td> <td style="vertical-align:top;"> <p>显示多行源代码</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>break</p> </td> <td style="vertical-align:top;"> <p>b</p> </td> <td style="vertical-align:top;"> <p>设置断点,程序运行到断点的位置会停下来</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>info</p> </td> <td style="vertical-align:top;"> <p>i</p> </td> <td style="vertical-align:top;"> <p>描述程序的状态</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>run</p> </td> <td style="vertical-align:top;"> <p>r</p> </td> <td style="vertical-align:top;"> <p>开始运行程序</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>display</p> </td> <td style="vertical-align:top;"> <p>disp</p> </td> <td style="vertical-align:top;"> <p>跟踪查看某个变量,每次停下来都显示它的值</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>step</p> </td> <td style="vertical-align:top;"> <p>s</p> </td> <td style="vertical-align:top;"> <p>执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>next</p> </td> <td style="vertical-align:top;"> <p>n</p> </td> <td style="vertical-align:top;"> <p>执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>print</p> </td> <td style="vertical-align:top;"> <p>p</p> </td> <td style="vertical-align:top;"> <p>打印内部变量值</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>continue</p> </td> <td style="vertical-align:top;"> <p>c</p> </td> <td style="vertical-align:top;"> <p>继续程序的运行,直到遇到下一个断点</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>set var name=v</p> </td> <td style="vertical-align:top;"> <p> </p> </td> <td style="vertical-align:top;"> <p>设置变量的值</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>start</p> </td> <td style="vertical-align:top;"> <p>st</p> </td> <td style="vertical-align:top;"> <p>开始执行程序,在main函数的第一条语句前面停下来</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>file</p> </td> <td style="vertical-align:top;"> <p> </p> </td> <td style="vertical-align:top;"> <p>装入需要调试的程序</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>kill</p> </td> <td style="vertical-align:top;"> <p>k</p> </td> <td style="vertical-align:top;"> <p>终止正在调试的程序</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>watch</p> </td> <td style="vertical-align:top;"> <p> </p> </td> <td style="vertical-align:top;"> <p>监视变量值的变化</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>backtrace</p> </td> <td style="vertical-align:top;"> <p>bt</p> </td> <td style="vertical-align:top;"> <p>产看函数调用信息(堆栈)</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>frame</p> </td> <td style="vertical-align:top;"> <p>f</p> </td> <td style="vertical-align:top;"> <p>查看栈帧</p> </td> </tr> <tr> <td style="vertical-align:top;"> <p>quit</p> </td> <td style="vertical-align:top;"> <p>q</p> </td> <td style="vertical-align:top;"> <p>退出GDB环境</p> </td> </tr> </tbody> </table> ![复制代码][copycode.gif] //e.c #include <stdio.h> void debug(char *str) { printf("debug info :%s\n",str ); } main(int argc,char *argv[]){ int i,j; j=0; for(i=0;i<10;i++){ j+=5; printf("now a=%d\n", j); } } ![复制代码][copycode.gif] gcc -g -o e e.c 调试gdb e 或者输入gdb 然后 file e list 命令用法 list命令显示多行源代码,从上次的位置开始显示,默认情况下,一次显示10行,第一次使用时,从代码其实位置显示 ![复制代码][copycode.gif] gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 main(int argc,char *argv[]){ 7 int i,j; 8 j=0; 9 for(i=0;i<10;i++){ 10 j+=5; (gdb) ![复制代码][copycode.gif] list n显示已第n行未中心的10行代码 ![复制代码][copycode.gif] (gdb) list 8 3 { 4 printf("debug info :%s\n",str ); 5 } 6 main(int argc,char *argv[]){ 7 int i,j; 8 j=0; 9 for(i=0;i<10;i++){ 10 j+=5; 11 printf("now a=%d\n", j); 12 } (gdb) ![复制代码][copycode.gif] list functionname显示以functionname的函数为中心的10行代码 ![复制代码][copycode.gif] (gdb) list main 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 main(int argc,char *argv[]){ 7 int i,j; 8 j=0; 9 for(i=0;i<10;i++){ 10 j+=5; (gdb) ![复制代码][copycode.gif] list - 显示刚才打印过的源代码之前的代码 ![复制代码][copycode.gif] (gdb) list 10 5 } 6 main(int argc,char *argv[]){ 7 int i,j; 8 j=0; 9 for(i=0;i<10;i++){ 10 j+=5; 11 printf("now a=%d\n", j); 12 } 13 }(gdb) list - 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); (gdb) ![复制代码][copycode.gif] 断点命令break break location:在location位置设置断点,改位置可以为某一行,某函数名或者其它结构的地址 GDB会在执行该位置的代码之前停下来 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 main(int argc,char *argv[]){ 7 int i,j; 8 j=0; 9 for(i=0;i<10;i++){ 10 j+=5; (gdb) 11 printf("now a=%d\n", j); 12 } 13 }(gdb) break 10 Breakpoint 1 at 0x40050a: file e.c, line 10. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10 10 j+=5; (gdb) c Continuing. now a=5 Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10 10 j+=5; (gdb) c Continuing. now a=10 Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10 10 j+=5; (gdb) ![复制代码][copycode.gif] 使用delete breakpoints 断点号 删除断点 这里的断点号表示的是第几个断点,刚才执行break 10返回 reakpoint 1 at 0x40050a: file e.c, line 10. 中的1表示该断点的标号,因此使用 delete breakpoints 1表示删除第10行所定义的断点 clear n表示清除第n行的断点,因此clear 10等同于delete breakpoints 1 disable/enable n表示使得编号为n的断点暂时失效或有效 可使用info查看断点相关的信息 info breakpoints ![复制代码][copycode.gif] gdb) info breakpoints No breakpoints or watchpoints. (gdb) break 10 Breakpoint 2 at 0x40050a: file e.c, line 10. (gdb) break 9 Breakpoint 3 at 0x400501: file e.c, line 9. (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y 0x000000000040050a in main at e.c:10 3 breakpoint keep y 0x0000000000400501 in main at e.c:9 ![复制代码][copycode.gif] display命令 查看参数的值 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) break 10 Breakpoint 1 at 0x40050a: file e.c, line 10. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10 10 j+=5; (gdb) display j 1: j = 0 (gdb) c Continuing. now a=5 Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10 10 j+=5; 1: j = 5 (gdb) display 1: j = 5 (gdb) display i 2: i = 1 (gdb) display j 3: j = 5 (gdb) display j*2 4: j*2 = 10 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 4: y j*2 3: y j 2: y i 1: y j ![复制代码][copycode.gif] 也可以使用disable,enable,delete,info命令修改及查看其状态,用法与对断点的一样 step及next命令 step可使得程序逐条执行,即执行完一条语句然后在吓一跳语句前停下来,等待用户的命令 一般使用step命令是,可使用display或者watch命令查看变量的变化,从而判断程序行为是否符合要求 当下一条指令为函数时,s进入函数内部,在其第一条语句前停下来 step n,next n 表示连续但不执行n条指令,如果期间遇到断点,则停下来 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 7 main(int argc,char *argv[]){ 8 int i,j; 9 j=0; 10 for(i=0;i<10;i++){ (gdb) 11 j+=5; 12 printf("now j=%d\n", j); 13 debug("x=======x"); 14 } 15 }(gdb) Line number 16 out of range; e.c has 15 lines. (gdb) break 11 Breakpoint 1 at 0x40050a: file e.c, line 11. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:11 11 j+=5; (gdb) s 12 printf("now j=%d\n", j); (gdb) s __printf (format=0x400648 "now j=%d\n") at printf.c:30 30 { (gdb) bt #0 __printf (format=0x400648 "now j=%d\n") at printf.c:30 #1 0x0000000000400525 in main (argc=1, argv=0x7fffffffe538) at e.c:12 (gdb) n 34 va_start (arg, format); (gdb) n 35 done = vfprintf (stdout, format, arg); (gdb) n now j=5 39 } (gdb) bt #0 __printf (format=<value optimized out>) at printf.c:39 #1 0x0000000000400525 in main (argc=1, argv=0x7fffffffe538) at e.c:12 (gdb) n main (argc=1, argv=0x7fffffffe538) at e.c:13 13 debug("x=======x"); (gdb) n debug info :x=======x 10 for(i=0;i<10;i++){ (gdb) s Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:11 11 j+=5; (gdb) s 12 printf("now j=%d\n", j); (gdb) n now j=10 13 debug("x=======x"); (gdb) n debug info :x=======x 10 for(i=0;i<10;i++){ (gdb) ![复制代码][copycode.gif] watch watch可设置观察点(watchpoint)。使用观察点可以使得当某表达式的值发生变化时,程序暂停执行。 执行该命令前,必须保证程序已经运行 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 7 main(int argc,char *argv[]){ 8 int i,j; 9 j=0; 10 for(i=0;i<10;i++){ (gdb) 11 j+=5; 12 printf("now j=%d\n", j); 13 debug("x=======x"); 14 } 15 }(gdb) Line number 16 out of range; e.c has 15 lines. (gdb) b main Breakpoint 1 at 0x4004fa: file e.c, line 9. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:9 9 j=0; (gdb) watch j Hardware watchpoint 2: j (gdb) c Continuing. Hardware watchpoint 2: j Old value = 0 New value = 5 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=5 debug info :x=======x Hardware watchpoint 2: j Old value = 5 New value = 10 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); ![复制代码][copycode.gif] print命令 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 7 main(int argc,char *argv[]){ 8 int i,j; 9 j=0; 10 for(i=0;i<10;i++){ (gdb) 11 j+=5; 12 printf("now j=%d\n", j); 13 debug("x=======x"); 14 } 15 }(gdb) Line number 16 out of range; e.c has 15 lines. (gdb) break 12 Breakpoint 1 at 0x40050e: file e.c, line 12. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) p j $1 = 5 (gdb) c Continuing. now j=5 debug info :x=======x Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) p i,j $2 = 10 (gdb) p j $3 = 10 (gdb) ![复制代码][copycode.gif] set var name=value 在程序运行中动态改变变量的值 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 7 main(int argc,char *argv[]){ 8 int i,j; 9 j=0; 10 for(i=0;i<10;i++){ (gdb) 11 j+=5; 12 printf("now j=%d\n", j); 13 debug("x=======x"); 14 } 15 }(gdb) Line number 16 out of range; e.c has 15 lines. (gdb) break main Breakpoint 1 at 0x4004fa: file e.c, line 9. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:9 9 j=0; (gdb) watch i Hardware watchpoint 2: i (gdb) watch j Hardware watchpoint 3: j (gdb) c Continuing. Hardware watchpoint 3: j Old value = 0 New value = 5 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=5 debug info :x=======x Hardware watchpoint 2: i Old value = 0 New value = 1 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) c Continuing. Hardware watchpoint 3: j Old value = 5 New value = 10 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=10 debug info :x=======x Hardware watchpoint 2: i Old value = 1 New value = 2 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) c Continuing. Hardware watchpoint 3: j Old value = 10 New value = 15 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=15 debug info :x=======x Hardware watchpoint 2: i Old value = 2 New value = 3 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) c Continuing. Hardware watchpoint 3: j Old value = 15 New value = 20 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=20 debug info :x=======x Hardware watchpoint 2: i Old value = 3 New value = 4 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) set var i=8 (gdb) c Continuing. Hardware watchpoint 3: j Old value = 20 New value = 25 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=25 debug info :x=======x Hardware watchpoint 2: i Old value = 8 New value = 9 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) c Continuing. Hardware watchpoint 3: j Old value = 25 New value = 30 main (argc=1, argv=0x7fffffffe538) at e.c:12 12 printf("now j=%d\n", j); (gdb) c Continuing. now j=30 debug info :x=======x Hardware watchpoint 2: i Old value = 9 New value = 10 0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10 10 for(i=0;i<10;i++){ (gdb) c Continuing. Watchpoint 2 deleted because the program has left the block in which its expression is valid. Watchpoint 3 deleted because the program has left the block in which its expression is valid. __libc_start_main (main=0x4004eb <main>, argc=1, ubp_av=0x7fffffffe538, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x7fffffffe528) at libc-start.c:258 258 exit (result); (gdb) c Continuing. Program exited with code 026. ![复制代码][copycode.gif] 函数调用相关的 backtrace 可使用frame 查看堆栈中某一帧的信息 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] (gdb) list 1 #include <stdio.h> 2 void debug(char *str) 3 { 4 printf("debug info :%s\n",str ); 5 } 6 7 main(int argc,char *argv[]){ 8 int i,j; 9 j=0; 10 for(i=0;i<10;i++){ (gdb) 11 j+=5; 12 printf("now j=%d\n", j); 13 debug("x=======x"); 14 } 15 }(gdb) Line number 16 out of range; e.c has 15 lines. (gdb) b 13 Breakpoint 1 at 0x400525: file e.c, line 13. (gdb) r Starting program: /mnt/hgfs/www/c/gcc/e1 now j=5 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:13 13 debug("x=======x"); (gdb) s debug (str=0x400652 "x=======x") at e.c:4 4 printf("debug info :%s\n",str ); (gdb) bt #0 debug (str=0x400652 "x=======x") at e.c:4 #1 0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13 (gdb) s __printf (format=0x400638 "debug info :%s\n") at printf.c:30 30 { (gdb) bt #0 __printf (format=0x400638 "debug info :%s\n") at printf.c:30 #1 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4 #2 0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13 (gdb) s 34 va_start (arg, format); (gdb) bt #0 __printf (format=0x400638 "debug info :%s\n") at printf.c:34 #1 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4 #2 0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13 (gdb) s 35 done = vfprintf (stdout, format, arg); (gdb) s _IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:236 236 int save_errno = errno; (gdb) bt #0 _IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:236 #1 0x000000333a24effa in __printf (format=<value optimized out>) at printf.c:35 #2 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4 #3 0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13 (gdb) c Continuing. debug info :x=======x now j=10 Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:13 13 debug("x=======x"); (gdb) bt #0 main (argc=1, argv=0x7fffffffe538) at e.c:13 ![复制代码][copycode.gif] [https_www.cnblogs.com_HKUI_p_8955443.html]: https://www.cnblogs.com/HKUI/p/8955443.html [copycode.gif]: /images/20220329/4453c862598049419527b6c688d37d2b.png [ExpandedBlockStart.gif]: /images/20220329/52b7c54c569642b8bb90fc1a3b81fbd5.png
相关 GDB调试 文章目录 * * 1、gdb调试编译准备 * 2、开启gdb调试 * 3、查看程序 l * 4、断点 . b *... 痛定思痛。/ 2024年04月19日 13:17/ 0 赞/ 189 阅读
相关 gdb 调试 信息显示命令 [info address][] [info registers][] [info files][] [info functions][ 灰太狼/ 2023年06月03日 15:58/ 0 赞/ 126 阅读
相关 GDB调试 不错的文章: [GDB调试][GDB] [GDB调试入门,看这篇就够了][GDB 1] [GDB]: https://blog.csdn.net/Hou_Rj/ar 淩亂°似流年/ 2023年05月31日 06:50/ 0 赞/ 7 阅读
相关 GDB调试 一.快速进阶 1.编译生成可执行文件 gcc -g test.c -otest 2.启动gdb gdb test 3.在main函数处打断点。 bre 爱被打了一巴掌/ 2022年09月24日 11:21/ 0 赞/ 398 阅读
相关 GDB 调试 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现G 朱雀/ 2022年08月27日 04:47/ 0 赞/ 453 阅读
相关 gdb 调试 基本用法 1. gcc -g xx.c xx 2. gdb xx 基本命令 1. start 启动程序, 默认停留在main程序的第一行 2. run 启 刺骨的言语ヽ痛彻心扉/ 2022年06月09日 11:26/ 0 赞/ 454 阅读
相关 gdb调试 在用gcc编程的时候可能会出bug,这时候就可以通过gdb这个工具进行调试,gdb调试的一定是直接有\.c 文件生成的bebug版本的可执行文件,否则,进入gdb之后敲入lis Dear 丶/ 2022年06月02日 07:55/ 0 赞/ 510 阅读
相关 gdb调试 要使用gdb调试,必须在源代码生成二进制程序的时候,加上-g选项 gdb常用命令: list/l + 行号:显示源代码,接着上次的位置往下列每次10行 li Love The Way You Lie/ 2022年05月14日 04:06/ 0 赞/ 450 阅读
相关 GDB调试 [https://www.cnblogs.com/HKUI/p/8955443.html][https_www.cnblogs.com_HKUI_p_8955443.html] 曾经终败给现在/ 2022年03月29日 17:38/ 0 赞/ 504 阅读
相关 GDB调试 另外有: Gdb+core调试技术 http://zhwen.org/xlog/?p=453 一、gdb简介和安装 GDB是GNU开源组织发 谁践踏了优雅/ 2022年01月22日 04:29/ 0 赞/ 506 阅读
还没有评论,来说两句吧...