(1)编译生成执行文件
# gcc -g tst.c -o tst
注意 -g 选项不可没有,否则gdb的l命令不能列出源文件内容
(2)启动GDB
gdb ./tst
若想一边调式,程序代码可以同步显示,则执行 gdb -tui ./test (建议这样调试)
(3)gdb常用命令
(gdb) help <------------- 帮助
(gdb) help running <-------- 显示running类别下的命令
(gdb) l <-------------------- l命令相当于list,从第一行开始例出源代码码。
(gdb) 回车 <-------------------- 直接回车表示重复上一次命令
断点:
(gdb) break 137 <-------------------- 设置断点,在当前文件(一般是main函数所在文件中)中源程序第137行处。
Breakpoint 1 at 0x400de6: file readxml.c, line 137.
(gdb) break func <-------------------- 设置断点,在当前文件(一般是main函数所在文件中)中源程序的函数func()入口处。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) break ana_balance.c: 12 <-------------------- 在文件ana_balance.c中的12行设置断点。
(gdb) break procxmldata.c: analyze <-------------------- 在文件procxmldata.c:中的函数analyze处设置断点。
说明:
这些代码文件可能在当前目录下的某个子目录中,gdb 会自动找到,在gdb状态下使用tab键直接补齐,不需要输入绝对路径
(gdb) info break 3 或者 info watchpoints 3 <-------------------- 查看断点3的信息
(gdb) info break <-------------------- 查看所有断点信息。
Num Type Disp Enb Address What
1 breakpoint keep y <PENDING> cluster.c
2 breakpoint keep y 0x0000000000407ce8 in load_balance at ./analyze/ana_balance.c:12
3 breakpoint keep y <PENDING> ana_balance.c: load_balacne
4 breakpoint keep y 0x0000000000404196 in analyze at ./main/procxmldata.c:1154
说明:PENDING 状态时指当前断点处于挂起状态,例如 文件 ana_balance.c 中没有 load_balacne 函数时就会如此。
断点信息:
*Breakpoint Numbers*----断点号
*Type*----断点类型(断点或是观察点)
*Disposition*---显示断点的状态。
*Enabled or Disabled*---使能或不使能。'y'表示使能,'n'表示不使能。
*Address*----地址,断点在你程序中的地址(内存地址)
*What*---地址,断点在你程序中的行号。
(gdb) delete 1 <-------------------- 删除断点号是1的断点,删除它后,其它断点的编号仍不变
(gdb) info break
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000407ce8 in load_balance at ./analyze/ana_balance.c:12
3 breakpoint keep y <PENDING> ana_balance.c: load_balacne
4 breakpoint keep y 0x0000000000404196 in analyze at ./main/procxmldata.c:1154
执行:
(gdb) r <--------------------- 运行程序,run命令简写,实际是running 类别下的r命令,也可写成 run、 running
run <arg1> <arg2> <--------------------------- 若程序带有命令行参数,则这样运行
(gdb) n <--------------------- 单步调式
(gdb) until NUM <--------------------- 执行到一个比当前行号大的行
(gdb) p tmpstr <--------------------- 打印变量的值
(gdb) c <----------------- 程序继续执行直到下一个断点
(gdb) finish 执行完成
(gdb) q 退出gdb
=========================================================================
(gdb) start $1 $2 ----- 从程序开始一步一步执行;如果遇到变量声明且无赋初值的语句,start会跳过,若变量声明时要赋初值,start不会跳过变量定义语句。
(gdb) run(缩写是 r) $1 $2 ----- 从头开始执行程序而非单步执行
(gdb) next(缩写是 n) ----- 程序单步执行,遇到函数调用也当做一行执行
(gdb) step(缩写是 s) ----- 程序单步执行,遇到函数进入函数内部
(gdb) backtrace(缩写是bt) ----- 函数调用栈帧(step命令执行时,调用的函数才会在栈中显示)
#0 getRegionNumFromFile (xmlfilepath=0x7fffffffe4f0 "data/ST_orgzkl_16nodes_1198shot_2011-3-29_zkl/MPI.tree") at ./main/procxmldata.c:1143
#1 0x00000000004046a4 in readTreeXmlData (treefilepath=0x7fffffffe4f0 "data/ST_orgzkl_16nodes_1198shot_2011-3-29_zkl/MPI.tree") at ./main/procxmldata.c:1016
#2 0x0000000000401138 in main (argc=8, argv=0x7fffffffe6e8) at ./main/procxmldata.c:154
(gdb) frame(缩写是f) ----- 查看当前栈帧
#0 getRegionNumFromFile (xmlfilepath=0x7fffffffe4f0 "data/ST_orgzkl_16nodes_1198shot_2011-3-29_zkl/MPI.tree") at ./main/procxmldata.c:1143
1143 int k=0;
(gdb) info(缩写i) locals ----- 查看当前栈帧中的局部变量
(gdb) frame 2 ----- 选择编号是2的栈帧
#2 0x0000000000401138 in main (argc=8, argv=0x7fffffffe6e8) at ./main/procxmldata.c:154
154 node=readTreeXmlData( treefilepath );
(gdb) finish ----- 让程序一直运行到从当前函数返回为止,例如进入了某个函数,运行了几行后,想运行完当前函数,返回到函数调用处
(gdb) list(缩写l) ----- 列出源代码,接着上次的位置往下列,每次列10行
(gdb) list 行号 ----- 列出从第几行开始的源代码,例如 l 0
(gdb) list 函数名 ----- 列出某个函数的源代码
(gdb) continue(缩写为c) ----- 连续运行而非单步运行,程序到达断点会自动停下来;循环中存在断点时经常使用
(gdb) display region_num,procsNum ----- 跟踪变量,程序每执行一行都显示region_num,procsNum两个变量的值,每使用一次display,他都将会为当前设计计数
2: region_num,procsNum = 0
1: region_num = 0
(gdb) undisplay 2 ----- 取消编号2对应的变量的显示
(gdb) break(缩写是b) 行号或函数名 ----- 在某行或者函数开头处设置断点
(gdb) i b
(gdb) info break
(gdb) info breakpoint
(gdb) info breakpoints ----- 查看所有断点信息
Num Type Disp Enb Address What
4 breakpoint keep y 0x0000000000400ec1 in main at ./main/procxmldata.c:9
5 breakpoint keep y 0x0000000000400ec1 in main at ./main/procxmldata.c:19
(gdb) delete(缩写d、del) breakpoint(缩写break,b) ----- 删除所有断点
(gdb) delete(缩写d、del) breakpoint(缩写break,b) $num ----- 删除编号是 $num 的断点
(gdb) disable breakpoints ----- 禁用断点:有时候一个断点暂时不想用可以禁用掉而不必删除,这样以后想用的时候可以直接启用
(gdb) enable breakpoints ----- 开启断点
断点是当程序执行到某一代码行时中断,而观察点是当程序访问某一存储单元时中断,如果我们不知道某一存储单元是在哪里被改动的,这时候观察点尤其有用
(gdb) watch 变量 ----- 设置观察点
(gdb) info watchpoints(或watch,watchpoint) ----- 查看当前设置了哪些观察点
(gdb) x ------ 从某个位置开始打印存储器的一段内容,全部当成字节来看,而不区分哪些字节属于哪些变量
=========================================================================
参考资料: