GDB使用简明教程

一、在编译的时候为什么要加-g

如果没有-g就看不见函数名,变量名,所代替的全是运行时的内存地址。


二、如何查看和使用core文件

首先通过指令ulimit -a查看系统是否允许生成core文件,可以通过指令ulimit -c unlimited取消系统对core文件的限制,ulimit -c 1024指定core文件的大小。

首先,我先编写一个会导致core dump的程序:

#include 

void f(char* a)
{
    a[2] = '2';
}

int main() 
{
    char* a = "1";
    f(a);
    return 0;
}
注意:编译的时候需要加上-g选项,否则gdb不知道程序符号。

运行程序,提示“段错误(核心已转储)”。

ls查看当前目录发现多了一个core文件

使用gdb解析core文件:gdb ./core_dump --core=core

[New LWP 7783]
Core was generated by `./core_dump'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000004004fd in f (a=0x4005b4 "1") at core_dump.c:5
5    a[2] = '2';
这样就可以查看到段错误的地方了~


三、设置断点、监控点和单步调试

(1)break + 函数名 或者 break + 行号 break filename:linenum,设置断点
info breakpoints(info b),显示当前程序的所有断点情况
(2)watch + expr 为表达式expr设置一个观察点,一旦表达式值有变化,马上停止
rwatch +expr 当expr被读时,停止程序
awatch + expr 当expr被读或写时,停止程序
info watchpoints 列出当前所设置的所有观察点
(3)catch 捕捉点
(4)disable + 断点号,不写断点号则disable所有断点
enable 使断点工作一次,之后又无效
delete + 断点号,删除某个断点
clear + 行号,清除该行的断点
(5)continue 恢复程序运行直到程序结束
step: 单步(进入函数调用)F11
next: 单步(不进入函数调用)F10
stepi和 nexti: 运行程序直到退出循环体
until(u):运行程序直到退出循环体; until+行号: 运行至某行 。需要把光标停止在循环的头部,然后输入u这样就自动执行全部的循环了
finish: 运行程序,直到当前函数完成返回再停止,并打印函数返回时的堆栈地址和返回值及参数值等信息。例如进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish.
call 函数(参数):调用“函数”,并传递“参数”,如:call gdb_test(55)
kill:输入kill终止正在调试的程序
(6) break thread NO. 在指定线程上设断点,否则所有线程都被中止


四、查看当前的调用堆栈

backtrace(bt)


五、多线程如何调试

(1)info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。
(2)thread ID 切换当前调试的线程为指定ID的线程。
(3)break file.c:100 thread all 在file.c文件第100行处为所有经过这里的线程设置断点。

(4)set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。 off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

(5)thread apply ID1 ID2 command
让一个或者多个线程执行GDB命令command。
(6)thread apply all command
让所有被调试线程执行GDB命令command。


六、打印信息

(1)print + 表达式:其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
(2)display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a

你可能感兴趣的:(linux)