1.1.1 断点commands高级功能
大多数时候需要在断点处执行一系列动作,gdb提供了在断点处执行命令的高级功能commands。
[](javascript:void(0)😉
#include <stdio.h>
int total = 0;
int square(int i)
{
int result=0;
result = i*i;
return result;
}
int main(int argc, char **argv)
{
int i;
for(i=0; i<10; i++)
{
total += square(i);
}
return 0;
}
[](javascript:void(0)😉
比如需要对如上程序square参数i为5的时候断点,并在此时打印栈、局部变量以及total的值
编写gdb.init如下:
[](javascript:void(0)😉
set logging on gdb.log
b square if i == 5
commands
bt full
i locals
p total
print "Hit break when i == 5"
end
[](javascript:void(0)😉
在gdb shell中source gdb.init,然后r执行命令,结果如下:
可以看出断点在i==5的时候断住了,并且此时打印了正确的值。
1.2 运行
“gdb 命令”之后,run可以在gdb下运行命令;如果命令需要参数则跟在run之后。
如果需要断点在main()处,直接执行start就可以。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YzvVHEuU-1585295253006)(C:\Users\w00448203\AppData\Roaming\Typora\typora-user-images\1585212705097.png)]
1.3 显示栈帧
如果遇到断点而暂停执行,或者coredump可以显示栈帧。
通过bt可以显示栈帧,bt full可以显示局部变量。
命令格式如下:
bt
bt full:不仅显示backtrace,还显示局部变量
bt N:显示开头N个栈帧
bt full N
1.4 显示变量
“print 变量”可以显示变量内容。
如果需要一行监控多个变量,可以通过p {var1, var2, var3}。
如果要跟踪自动显示,可以使用display {var1, var2, var3}
1.5 显示寄存器
info reg可以显示寄存器内容。
在寄存器名之前加$可以显示寄存器内容,
p $寄存器:显示寄存器内容
p/x $寄存器:十六进制显示寄存器内容。
用x命令可以显示内容内容,“x/格式 地址”。
x $pc:显示程序指针内容
x/i $pc:显示程序指针汇编。
x/10i $pc:显示程序指针之后10条指令。
x/128wx 0xfc207000:从0xfc20700开始以16进制打印128个word。
1.9 改变变量的值
“通过set variable <变量>=<表达式>”来修改变量的值。
set $r0=xxx:设置r0寄存器的值为xxx。
1.13 初始化文件
Linux环境下初始化文件为.gdbinit。
如果存在.gdbinit文件,gdb在启动的之前就将其作为命令文件运行。
初始化文件和命令文件执行顺序为:HOME/.gdbinit > 运行命令行选项 > ./.gdbinit > -x指定命令文件。
define命令宏
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-riD7IU4v-1585295253009)(C:\Users\w00448203\AppData\Roaming\Typora\typora-user-images\1585293921956.png)]
用define创建的命令宏,可以与commands内使用,很灵活。
https://www.cnblogs.com/arnoldlu/p/9633254.html
1.14 gdb commands命令用法
//设置断点
(gdb) b rx_data
Breakpoint 1 at 0xffffffffa02cccf8: file drivers/target/iscsi/iscsi_target_util.c, line 1347.
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
/*输入当运行到断点时想执行的命令(单个或多个),输入end表示命令输入完成
例子中表示,打印c.iov的值,以及继续执行,两条命令*/
>p c.iov
>c
>end
/*设置完成后,输入info br,会出现类似以下的提示*/
(gdb) info br
Num Type Disp Enb Address What
1 breakpoint keep y 0xffffffffa02cccf8 in rx_data at drivers/target/iscsi/iscsi_target_util.c:1347
p c.iov
c
/*如果有多个断点,需要设置不同断点被断住时自动执行的命令,则可输入commands num实现设置,例如:*/
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>p c.type
>c
>end
/*结果如下*/
(gdb)info br
Num Type Disp Enb Address What
1 breakpoint keep y 0xffffffffa02cccf8 in rx_data at drivers/target/iscsi/iscsi_target_util.c:1347
p c.type
c
/*如果想清空断点的命令,输入commands num后,直接输入end即可*/
(gdb)commands 1
>end
(gdb)info br
(gdb)info br
Num Type Disp Enb Address What
1 breakpoint keep y 0xffffffffa02cccf8 in rx_data at drivers/target/iscsi/iscsi_target_util.c:1347
/*在运行过程中经常出现: --Type <return> to continue, or q<return> to quit. 程序就被阻塞了,需要人手动敲一下回车才能继续。可通过设置height解决*/
(gdb)set height 0
fffa02cccf8 in rx_data at drivers/target/iscsi/iscsi_target_util.c:1347
/在运行过程中经常出现: --Type to continue, or q to quit. 程序就被阻塞了,需要人手动敲一下回车才能继续。可通过设置height解决/
(gdb)set height 0