1. 准备
代码若要支持GDB调试,需要加入-g 信息:
- 通过gcc的-g选项生成调试信息:
$gcc -g 源文件
- 通过makefile构建,需要在CFLAGS中指定-g选项:
CFLAGS = -g
- 通过configure脚本生成makefile:
./configure CFLAGS="-g"
1.1 GDB 常用命令
命令 | 简写 | 说明 |
backstrace | bt,where | 显式栈信息 |
break | b | 设置断点 |
continue | c | 继续运行 |
delete | d | 删除断点 |
finish | 运行到函数结束 | |
info breakpoints | info b | 显式断点信息 |
next | n | 执行下一行 |
p | 打印显式 | |
run | r | 执行程序 |
step | s | 进入函数内部 |
x | 显式内存内容 | |
util | u | 执行到指定行 |
directory | dir | 插入目录 |
disable | dis | 禁用断点 |
down | do | 在当前调用的帧栈中选择要显式的帧栈 |
edit | e | 编辑文件或函数 |
frame | f | 选择要显式的帧栈 |
forward-search | fo | 向前搜索 |
generate-core-file | gcore | 生成内核转储 |
help | h | 显式帮助一览 |
info | i | 显式信息 |
list | l | 显式函数或行 |
nexti | ni | 执行汇编代码下一行 |
stepi | si | 执行汇编代码下一行 |
print-object | po | 显式目标信息 |
sharedlibrary | share | 加载共享库的符号 |
2. 启动
gdb 可执行文件名
3. 断点 break
3.1 设置断点
格式:
b 函数名
b 行号
b 文件名:行号
b 文件名:函数名
b +偏移量 //现在暂停位置往后n行
b -偏移量 //现在暂停位置往前n行
b *地址
3.2 查看断点信息
info b
断点举例:
设置断点
gdb) b SnoopMain:54
Breakpoint 1 at 0x85b3970: file /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c, line 46.
(gdb) b SnoopMainModuleInit
Breakpoint 2 at 0x85b31f0: file /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c, line 551.
查看断点信息
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x085b3970 in SnoopMain
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:46
2 breakpoint keep y 0x085b31f0 in SnoopMainModuleInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:551
3.3 运行run
用run命令开始运行,不加参数,则会执行到断点处暂停。
举例:
(gdb) r
Starting program: /home/toney/work/project/dragon/x86_run/x86_ISS.exe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
[CmSingleFwBidStrGet #156]Can't get board id string! The first Board Profile config will be used!
cp: cannot stat ‘issdefault_DBS-1210-10MP.conf’: No such file or directory
[New Thread 0x4002cd80 (LWP 3092)]
[New Thread 0x40c52ec0 (LWP 3093)]
Device Discovery ........................................ [New Thread 0x40e52ec0 (LWP 3094)]
Breakpoint 1, SnoopMain (pi1Param=pi1Param@entry=0x0)
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:46
46 {
(gdb)
3.4 显式帧栈backtrace (bt)
bt命令可以在遇到断点的时候暂停显式帧栈信息,其还有别名 where, info stack
格式:
bt
bt N //显式最后的N个帧栈
bt -N //显式最开始的N个帧栈
举例:
(gdb) bt
#0 SnoopMain (pi1Param=pi1Param@entry=0x0) at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:46
#1 0x087e2870 in OsixTskWrapper (pArg=0x9dc6238 <gaOsixTsk+2584>) at pthreads/osixpth.c:1366
#2 0x40047f72 in start_thread (arg=0x46b7fec0) at pthread_create.c:312
#3 0x4018ff8e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
(gdb) bt 2
#0 SnoopMain (pi1Param=pi1Param@entry=0x0) at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:46
#1 0x087e2870 in OsixTskWrapper (pArg=0x9dc6238 <gaOsixTsk+2584>) at pthreads/osixpth.c:1366
(More stack frames follow...)
(gdb) bt -2
#2 0x40047f72 in start_thread (arg=0x46b7fec0) at pthread_create.c:312
#3 0x4018ff8e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
3.5 显式变量print (p)
格式:
p 变量
举例:
(gdb) p u4Events
$3 = 165438008
3.6 显式寄存器 info registers
举例:
(gdb) info reg
eax 0xc5c 3164
ecx 0x0 0
edx 0xc5c 3164
ebx 0x9dc6238 165438008
esp 0x46b7f6ac 0x46b7f6ac
ebp 0x46b7f7a8 0x46b7f7a8
esi 0x85b3970 140196208
edi 0x0 0
eip 0x85b3970 0x85b3970 <SnoopMain>
eflags 0x206 [ PF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
3.6.1 显式寄存器内容:
(gdb) p $eax
$4 = 3164
指定格式显式寄存器内容:
格式:
x 显式为十六进制数
d 显式为十进制数
u 显式为无符号十进制数
o 显式为八进制数
t 显式为二进制数 two
a 地址
c 显式为字符
f 浮点小数
s 显式为字符串
i 显式为机器语言(汇编语言),仅在显式内存的x命令中使用
举例:
(gdb) p/c $eax
$5 = 92 '\\'
3.6.2 显式内存的内容
格式:
x/NFU 地址
其中,
N为重复次数
F为格式: x,d,u,o,t,a,c,f,s,i
U表示单位:b字节 h半字 w字 g双字
举例:
(gdb) x $pc
0x85b3970 <SnoopMain>: 83 'S'
(gdb) x/i $pc
=> 0x85b3970 <SnoopMain>: push %ebx
(gdb) x/10i $pc
=> 0x85b3970 <SnoopMain>: push %ebx
0x85b3971 <SnoopMain+1>: sub $0x28,%esp
0x85b3974 <SnoopMain+4>: movl $0x0,0x1c(%esp)
0x85b397c <SnoopMain+12>: call 0x85b1350 <SnoopTaskInit>
0x85b3981 <SnoopMain+17>: test %eax,%eax
0x85b3983 <SnoopMain+19>: jne 0x85b3b76 <SnoopMain+518>
0x85b3989 <SnoopMain+25>: call 0x85b3770 <SnoopMainStartModule>
0x85b398e <SnoopMain+30>: test %eax,%eax
0x85b3990 <SnoopMain+32>: jne 0x85b3b3a <SnoopMain+458>
0x85b3996 <SnoopMain+38>: movl $0x9c3c978,(%esp)
3.7 单步执行
执行源代码中下一行的命令为next (n);
进入函数内部命令为step (s);
(如果要逐条执行汇编语言,可以使用nexti,stepi)
举例:
gdb) n
|47 UINT4 u4Events = 0;
(gdb) n
/56 if (SnoopTaskInit () != SNOOP_SUCCESS)
(gdb) n
-63 if (SnoopMainStartModule () != SNOOP_SUCCESS)
(gdb) s
\SnoopMainStartModule () at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:295
3.8 继续执行 continue
使用c命令继续执行程序,直到遇到断点后再次暂停执行。
格式:
c
c 次数 //指定后面忽略的断点数
举例:
(gdb) c
Continuing.
|
Breakpoint 2, CmSnpAcInit () at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
32 {
3.9 监视点
想要找到变量在什么地方改变,可以使用watch命令。
格式:
watch <表达式> // <表达式>的意思是常量或变量等,当其发生变化时暂停。
awatch <表达式> // <表达式>被访问,改变时暂停运行
rwatch <表达式> // <表达式>被访问时暂停运行
举例:
(gdb) watch gu4IgsSysLogId
Hardware watchpoint 1: gu4IgsSysLogId
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/toney/work/project/dragon/x86_run/x86_ISS.exe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
[CmSingleFwBidStrGet #156]Can't get board id string! The first Board Profile config will be used!
cp: cannot stat ‘issdefault_DBS-1210-10MP.conf’: No such file or directory
[New Thread 0x4002cd80 (LWP 3564)]
[New Thread 0x40c52ec0 (LWP 3565)]
Device Discovery ........................................ [New Thread 0x40e52ec0 (LWP 3566)]
[Switching to Thread 0x46b7fec0 (LWP 3582)]
Hardware watchpoint 1: gu4IgsSysLogId
Old value = 0
New value = 79
SnoopMain (pi1Param=pi1Param@entry=0x0) at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:112
112 lrInitComplete (OSIX_SUCCESS);
(gdb) bt
#0 SnoopMain (pi1Param=pi1Param@entry=0x0) at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:112
#1 0x087e2870 in OsixTskWrapper (pArg=0x9dc6238 <gaOsixTsk+2584>) at pthreads/osixpth.c:1366
#2 0x40047f72 in start_thread (arg=0x46b7fec0) at pthread_create.c:312
#3 0x4018ff8e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
(gdb)
3.10 删除断点和监视点delete
使用d命令删除断点和监视点
格式:
delete 编号
举例:
(gdb) b SnoopTaskInit
Breakpoint 1 at 0x85b1350: file /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c, line 244.
(gdb) b SnoopMainStartModule
Breakpoint 2 at 0x85b3770: file /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c, line 295.
(gdb) b CmSnpAcInit
Breakpoint 3 at 0x8611340: file /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c, line 32.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x085b1350 in SnoopTaskInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:244
2 breakpoint keep y 0x085b3770 in SnoopMainStartModule
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:295
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb) d 2
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x085b1350 in SnoopTaskInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:244
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb)
3.11删除断点和禁用断点
- clear 删除已定义的断点
clear
clear 函数名
clear 行号
clear 文件名:行号
clear 文件名:函数名
delete [breakpoints] 断点编号
- disable 临时禁用断点
disable [breakpoints]
disable [breakpoints] 断点编号
disable display 显式编号
disable mem 内存区域
- enable 将禁用的断点重新启用
enable [breakpoints]
enable [breakpoints] 断点编号
enable [breakpoints] once 断点编号
enable [breakpoints] delete 断点编号
enable display 显式编号
enable mem 内存区域
举例:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x085b1350 in SnoopTaskInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:244
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb) disable 1
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep n 0x085b1350 in SnoopTaskInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:244
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep n 0x085b1350 in SnoopTaskInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/snpmain.c:244
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb) clear snpmain.c:SnoopTaskInit
Deleted breakpoint 1
(gdb) info b
Num Type Disp Enb Address What
3 breakpoint keep y 0x08611340 in CmSnpAcInit
at /home/toney/work/project/dragon/core/code/future/snooping/snpcore/src/cmsnpac.c:32
(gdb)