一旦使用GDB挂上被调试程序,当程序运行起来后,你可以根据自己的调试思路来动态地在GDB中更改当前被调试程序的运行线路或是其变量的值,这个强大的功能能够让你更好的调试你的程序,比如,你可以在程序的一次运行中走遍程序的所有分支。
一、修改变量值- whatis [varname]
打印该变量的类型 - set var [varname] = 47
设置该变量的值
增加的代码:
int val = 0;
if(val == 0){
printf("go in the val0 casen");
}else if(val == 1){
printf("changed, go in the val1 casen");
}
gdb调试:
(gdb) break 27 Breakpoint 1 at 0x1290: file tst.c, line 27.
(gdb) r
Starting program: /home/ubuntu/learn_gdb/tst
Breakpoint 1, main (argc=1, argv=0x7fffffffe148) at tst.c:27
27 if(val == 0){
(gdb) whatis val type = int
(gdb) set var val = 1
(gdb) c Continuing. changed, go in the val1 case result[1-100] = 5050 result[1-250] = 31125 [Inferior 1 (process 3045980) exited normally]二、跳转执行
-
jump [linespec]
指定下一条语句的运行点。[linespce]可以是文件的行号,可以是file:line格式,可以是+num这种偏移量格式。表式着下一条运行语句从哪里开始
-
jump [address]
这里的[address]是代码行的内存地址。
-
set $pc = 0x485
熟悉汇编的人都知道,程序运行时,有一个寄存器用于保存当前代码所在的内存地址。所以,jump命令也就是改变了这个寄存器中的值。于是,你可以使用“set $pc”来更改跳转执行的地址。
(gdb) break 25 Breakpoint 1 at 0x1283: file tst.c, line 25.
(gdb) r Starting program: /home/ubuntu/learn_gdb/tst Breakpoint 1, main (argc=1, argv=0x7fffffffe148) at tst.c:25 25 j++;
(gdb) jump 27 Continuing at 0x55555555528b. j is: 1 go in the val0 case result[1-100] = 5050 result[1-250] = 31125 [Inferior 1 (process 3048823) exited normally]三、产生信号量
-
signal [singal]
使用singal命令,可以产生一个信号量给被调试的程序。如:中断信号Ctrl+C。这非常方便于程序的调试,可以在程序运行的任意位置设置断点,并在该断点用GDB产生一个信号量,这种精确地在某处产生信号非常有利程序的调试。UNIX的系统信号量通常从1到15。所以取值也在这个范围。
四、强制函数返回- return [expression]
如果你的调试断点在某个函数中,并还有语句没有执行完。你可以使用return命令强制函数忽略还没有执行的语句并返回。使用return命令取消当前函数的执行,并立即返回,如果指定了[expression],那么该表达式的值会被认作函数的返回值。
(gdb) break func Breakpoint 1 at 0x1189: file tst.c, line 4.
(gdb) r
Starting program: /home/ubuntu/learn_gdb/tst
go in the val0 case
result[1-100] = 5050
Breakpoint 1, func (n=32767) at tst.c:4
4 {
(gdb) s 5 int sum = 0, i; (gdb) s 6 for (i = 0; i < n; i++) (gdb) s 8 sum += i; (gdb) s 6 for (i = 0; i < n; i++) (gdb) s 8 sum += i; (gdb) s 6 for (i = 0; i < n; i++) (gdb) s 8 sum += i; (gdb) s 6 for (i = 0; i < n; i++)
(gdb) return 11
Make func return now? (y or n) y
#0 0x0000555555555316 in main (argc=1, argv=0x7fffffffe148) at tst.c:44
44 printf("result[1-250] = %d n", func(250));
(gdb) c Continuing. result[1-250] = 11 [Inferior 1 (process 3047076) exited normally]五、强制调用函数
-
call [expr]
表达式中可以一是函数,以此达到强制调用函数的目的。并显示函数的返回值,如果函数返回值是void,那么就不显示。
另一个相似的命令也可以完成这一功能——print,print后面可以跟表达式,所以也可以用他来调用函数,print和call的不同是,如果函数返回void,call则不显示,print则显示函数返回值,并把该值存入历史数据中。
用GDB调试程序(七)



