1. gdb 使用简介
1> 编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o test_exe
2> 直接使用gdb调试可执行文件: gdb test_exe
3> 然后进入gdb 模式,此时可添加断点,查看断点个数和信息, 删除断点。注意添加断点后,使用 run 命令让程序运行起来
break function_name
break filename:lineNum
break linename:lineNum if valName == value
info break
delete break_id
run
4> 使用 next step等命令让程序单步执行
5> 通过 list 列出代码行数,但是源码文件要和可执行文件或core文件 在相同路径下
list lineNum1,lineNum2
list-n
list+functionName
6> 设置变量的数值
set var VarName=x
7> 实时显示某个变量的数值,结合单步调试使用。使用dispaly会显示所有要观察的变量
display VarName
undisplay VarName
display
8>
set print pretty 按照层次打印结构体
set logging fileName 把 gdb log 存入文件 fileName
set logging on
set logging off
2. 删除断点 详细解释
delete可删除单个断点,也可删除一个断点的集合,这个集合用连续的断点号来描述。
例如:
delete 5
delete 1-10
clear 删除断点是基于行的,不是把所有的断点都删除。
用法:clear
删除所在行的多有断点。
clear location
clear 删除所选定的环境中所有的断点
clear location location描述具体的断点。
例如:
clear list.c:list_delet //删除文件:函数的所有断点
clear 12 //删除行号的所有断点
clear list.c:12 //删除文件:行号的所有断点
3. watch可以观察某个变量的数值,当变量值变化时,产生断点。
watch a -------观察a的值,当有变化时,停止
(gdb) watch a -------观察a的值,当有变化时,停止
Hardware watchpoint 2: a
(gdb) c -------继续执行,当a的值变化时停止
Continuing.
Hardware watchpoint 2: a
Old value = 0
New value = 1
watch也可以观察内存值变化,当内存值变化时,产生断点。这种方法对局部变量的作用有限,更多适用于全局变量和在堆上申请的内存。
暂使用局部变量 展示使用方法:
int a = 0;
printf("a = %d\n", a);
a = 3;
printf("a = %d\n", a);
=========== 运行到第一个printf 时,添加watch 命令
(gdb) p &a
(gdb) $2 = (int *) 0x7fffffffe43c
(gdb) watch *( (int *) 0x7fffffffe43c)
Hardare watchpoint 2: *( (int *) 0x7fffffffe43c)
(gdb) c
Hardare watchpoint 2: *( (int *) 0x7fffffffe43c)
old value = 0
new value = 3
(gdb)
2. 多线程调试
info threads 显示当前可调试的所有线程
thread ID 切换当前调试的线程为指定ID的线程
attach process-id 在gdb状态下,开始调试一个正在运行的进程
thread apply all command 所有线程执行command
3. 分两个窗口,一个查看代码,一个用于 调试
layout src
Ctrl+L 刷新代码
Ctrl+x + a 退出该模式,回到传统模式
4. gdb中的命令详细解释:
回车键:重复上一命令
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h
(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r
(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l
(gdb)set:设置变量的值
(gdb)next:单步调试(逐过程,函数直接执行),简写n
(gdb)step:单步调试(逐语句:跳入自定义函数内部执行),简写s
(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt
(gdb)frame:切换函数的栈帧,简写f
(gdb)info:查看函数内部局部变量的数值,简写i
(gdb)finish:结束当前函数,返回到函数调用点
(gdb)continue:继续运行,简写c
(gdb)print:打印值及地址,简写p
(gdb)quit:退出gdb,简写q
(gdb)break +num:在第num行设置断点,简写b,我测试时,+号前面应有空格,后面无空格
(gdb)info breakpoints:查看当前设置的所有断点
(gdb)delete breakpoints_num:删除第num个断点,简写d
(gdb)display:追踪查看具体变量值
(gdb)undisplay:取消追踪观察变量
(gdb)watch:被设置观察点的变量发生修改时,打印显示
(gdb)i watch:显示观察点
(gdb)enable breakpoints:启用断点
(gdb)disable breakpoints:禁用断点
(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元
(gdb)run argv[1] argv[2]:调试时命令行传参
(gdb)set follow-fork-mode child#Makefile项目管理:选择跟踪父子进程(fork())
core文件:先用$ ulimit -c 1024 开启core,当程序出错会自动生成core文件。调试时 gdb a.out core
ctrl+c:退出输入