【技术分享】GDB 程序动态调试
2022-05-06 / 0 评论 / 52 阅读 / 4 点赞

【技术分享】GDB 程序动态调试

发光的神
2022-05-06 / 0 评论 / 52 阅读 / 正在检测是否收录...

简介

gdb 是一个用来调试 C 和 C++ 程序的强力调试器,除支持 c/c++ 语言外还支持 go、D、object-c、fortran 等语言,它使你能在程序运行时观察程序的内部结构和内存的使用情况。

lbrh4jui.png

#include <stdio.h>

int count = 0;

void hint() {
    printf("The program is running\n");
}

int main() {
    hint();
    count = 1;
    printf("exit...");
    return 0;
}

1.这里用C写了一个例子,编译后会执行main里面的代码段,依次输出 The program is running 和 exit... 然后结束程序。

lbrgkue3.png

gcc test.c -g

2.这里编译一下,在默认的编译模式下是不具备有调试的,一定要加-g参数,才能进行gdb动态调试。

lbrgqwrq.png

gdb a.out

3.输入gdb加可执行文件,就可以进入调试内,接下来就要用到gdb内置语句进行操作了。

break 断点

lbrhftcz.png

b main // 函数断点
b /home/kali/Desktop/test.c:13 // 行数断点
b /home/kali/Desktop/test.c:13 if cnt==10 // 条件断点
b *0x400522 // 数据断点
b &变量名

layout 可视化视图

lbrj4iui.png

layout src

1.可以通过可视化视图进行调试,类似windows x64dbg一样。

run 运行

lbrhrtaq.png

1.r的时候在main函数内有很多个函数,这个时候就可以用s了它就会进入函数内部。

lbrhy0qd.png

r // 一直执行 run
s // 步入 step
n // 步过 next

2.看是不是进入hint函数内部执行了,默认情况下,run 指令会一直执行程序,直到执行结束。如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处,start 指令会执行程序至 main() 主函数的起始位置,即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。

kill 调试

lbri17s3.png

k // 结束当前调试

1.当我们在调试中想退出dbug调试可以输入k,这样就退出了。

info 查看

lbri50u3.png

lbri73oh.png

info b // 显示断点

d 1 2  // 删除断点

1.使用info b 可以查看我们下了哪些断点,使用d + 行数位置 可以将断点删除掉。

continue

lbrifmw3.png

watch

lbriw0bl.png

1.watch可以监视一旦变量发生变化就会停下来,这里我监视了一个全局变量count它是0到下面会被改变成1。

lbrj1qq1.png

info r // 查看通用寄存器

断点调试

break + 设置断点的行号    break n    在n行处设置断点
tbreak + 行号或函数名    tbreak n/func    设置临时断点,到达后被自动删除
break + filename + 行号    break main.c:10    用于在指定文件对应行设置断点
break + <0x...>    break 0x3400a    用于在内存某一位置处暂停
break + 行号 + if + 条件    break 10 if i==3    用于设置条件断点,在循环中使用非常方便
info breakpoints/watchpoints [n]    info break    n表示断点编号,查看断点/观察点的情况
clear + 要清除的断点行号    clear 10    用于清除对应行的断点,要给出断点的行号,清除时GDB会给出提示
delete + 要清除的断点编号    delete 3    用于清除断点和自动显示的表达式的命令,要给出断点的编号,清除时GDB不会给出任何提示
disable/enable + 断点编号    disable 3    让所设断点暂时失效/使能,如果要让多个编号处的断点失效/使能,可将编号之间用空格隔开
awatch/watch + 变量    awatch/watch i    设置一个观察点,当变量被读出或写入时程序被暂停
rwatch + 变量    rwatch i    设置一个观察点,当变量被读出时,程序被暂停
catch        设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常
tcatch        只设置一次捕捉点,当程序停住以后,应点被自动删除

数据命令

display +表达式    display a    用于显示表达式的值,每当程序运行到断点处都会显示表达式的值
info display        用于显示当前所有要显示值的表达式的情况
delete + display 编号    delete 3    用于删除一个要显示值的表达式,被删除的表达式将不被显示
disable/enable + display 编号    disable/enable 3    使一个要显示值的表达式暂时失效/使能
undisplay + display 编号    undisplay 3    用于结束某个表达式值的显示
whatis + 变量    whatis i    显示某个表达式的数据类型
print(p) + 变量/表达式    p n    用于打印变量或表达式的值
set + 变量 = 变量值    set i = 3    改变程序中某个变量的值

调试相关命令

set args    set args arg1 arg2    设置运行参数
show args    show args    参看运行参数
set width + 数目    set width 70    设置GDB的行宽
cd + 工作目录    cd ../    切换工作目录
run    r/run    程序开始执行
step(s)    s    进入式(会进入到所调用的子函数中)单步执行,进入函数的前提是,此函数被编译有debug信息
next(n)    n    非进入式(不会进入到所调用的子函数中)单步执行
finish    finish    一直运行到函数返回并打印函数返回时的堆栈地址和返回值及参数值等信息
until + 行数    u 3    运行到函数某一行
continue(c)    c    执行到下一个断点或程序结束
return <返回值>    return 5    改变程序流程,直接结束当前函数,并将指定值返回
call + 函数    call func    在当前位置执行所要运行的函数

堆栈相关命令

backtrace/bt    bt    用来打印栈帧指针
frame    frame 1    用于打印指定栈帧
info reg    info reg    查看寄存器使用情况
info stack    info stack    查看堆栈使用情况
up/down    up/down    跳到上一层/下一层函数
4

评论 (0)

取消
0:00