用gdb调试代码

gdb调试

1
$ gdb execfile

开始调试execfile;

list

list,简写为l,显示源文件;命令格式:

1
list | l [arg1,arg2]

arg1为起始行号,arg2为结束行号;显示arg1行到arg2行之间的代码;

未设置arg1和arg2 时,默认显示10行;

1
2
(gdb) l
#显示1-10行代码

break

break,简写b,设置断点;命令格式:

1
break | b location

location可以是function(函数名) | linenum(行号) | address(偏移地址);

1
2
3
(gdb) b _start
(gdb) b *_start + 4
(gdb) b 14

run、stepi、info
run

run,简写r,运行程序;

stepi

stepi,简写si,执行一条指令;命令格式:

1
stepi | si [N]

N意味着执行N条指令(或者到程序结束处);

1
2
3
4
(gdb) si
# 执行一条指令
(gdb) si 4
# 执行四条指令

info

info,简写i,显示一些调试信息;

1
2
3
4
info registers -- List of integer registers and their contents
#可以简写为 i r
info breakpoints -- Status of specified breakpoints (all user-settable breakpoints if no argument)
#简写 i b

print

print,简写pExamining Data,打印寄存器中的值或打印变量中的值;命令格式:

1
print | p [/fmt] $registers | variable

registers表示寄存器,如eax,ebx,ecx,edx,esi, edi, esp, ebp, eflags等;
fmt参数如下表:

format letter description
o octal
x hex
d decimal
u unsigned decimal
t binary
f float
a address
i instruction
c char
s string
z hex,zero padded on the left
1
2
3
4
(gdb) p $eax
#打印寄存器eax中的值
(gdb) p Snippet
#打印Snippet中的值
examine

x,全称:examine;Examining Memory,打印内存单元中的值;命令格式:

1
x/nfu address

address表示内存单元地址;
n是一个整数,表示显示几个内存单元;默认是1;
f表示格式化,见上表;默认是x;
u表示内存单元大小,见下表:

unit letter description
b Bytes
h HalfWords(two bytes)
w Words(four bytes, default)
g Giant words(eight bytes)
1
2
3
4
(gdb) x/5cb &Snippet
#从Snippet所在的地址开始打印连续的5个以字节为单位的内存单元,并以字符的形式显示;
(gdb) x/5cb 0x6000c8;
#从地址为0x6000c8的内存单元开始打印;
display

displayAutomatic Display,自动显示,每次运行完一条指令自动打印显示列表中的值;命令格式:

1
display[/fmt] expr | address

display会根据设置的fmt,expr或者address自动判断是调用x还是print

1
2
3
4
(gdb) display/5xb &Snippet
#等价于每次执行完一条指令后,自动执行一次x/5xb &Snippet;
(gdb) display/x $ebx
#相当于每次执行一条指令后,自动执行一次p/x $ebx;

quit

quit,简写q,退出gdb;

shell

需要在gdb中执行shell命令时,可以使用shell;命令格式:

1
shell command

TUI模式

gdb提供TUI(Text User Interface)模式,方便调试代码;

进入TUI模式

利用gdb -tui execfile命令进入gdb,可以开启TUI模式;
进入gdb之后通过快捷键ctrl+x a或者使用命令tui enable开启TUI模式;

layout

可以利用layout命令调整TUI中的布局;通过help layout可以查看帮助;命令格式:

1
layout next | prev | layoutname

next下一个布局,prev上一个布局,layoutname见下表:

layoutname description
src 源码布局
asm 汇编布局
split 源码,汇编,cmd布局
regs 寄存器布局
winheight

调整布局的大小,命令格式:

1
winheight winname [+ | -] lines

winname见下表:

winname description
src 源码窗口
asm 汇编窗口
cmd 命令窗口
regs 寄存器窗口

+表示窗口winname增大lines行,-表示窗口winname减小lines行;

focus

利用focus可以让焦点关注不同的窗口;命令格式:

1
focus next | prev | winname

next下一个窗口,prev上一个窗口,winname见上表;
当cmd不被focus时,在cmd中方向键不起作用,若要使用方向键,此时方向键命令同emacs一样(ctrl+p向上,ctrl+n向下,ctrl+f向右,ctrl+b向左);

refresh

refresh刷新窗口;

关闭TUI模式

ctrl+x a既可以开启TUI,也可以关闭TUI;
tui disable关闭TUI模式;

参考:
Debugging with GDB
Quick GDB Information