Article Directory
Preface
When writing this blog, I looked at the manual and turned on the virtual machine... I tried and summarized. After writing a few chapters, I found that the form was too streamlined, so I sorted it out again.
It's enough to learn simple use and normal debugging. The rest only needs to know that there is this function, forget it, just check the manual.
Recommended documents :
100 gdb tips (absolutely practical)
Debugging with gdb (Chinese version, with surprise at the beginning)
use
ready
I use makebmp.c
demo as an example below:
gcc -g -o makebmp makebmp.c
-g
The function of the option is to add source code information to the executable file.
For example: the executable file in the first few machine instructions corresponding to the first few lines of source code, but not the entire source file is embedded into the executable file, but must ensure that when debugging gdb
can find the source files.
- Get executable file
makebmp
start up
Then use the following command to call gdb
gdb makebmp
The default will print the above information, if feel an eyesore, you can use -q
itquiet
gdb -q makebmp
Start debugging
Into the gdb
future, we need to use:
start
This instruction is equivalent to
//main_linenumber 为主函数行号
//tb:设置临时断点
tb main_linenumber
//run 缩写:r
run
So how do we know which line of our source code is?
View source code
list
//缩写:l
By default, only 10 lines of code are displayed.
list
Related operations include:
// 指定行号,函数
list 1
list main
// 向前向后打印
list -
list +
// 指定打印范围
list 1,10
Single step debugging
next
//缩写
n
When the implementation of a custom function WriteBMP( )
during continued use of the single-step execution, the function will be executed completely in the next step.
If you want to enter the function for debugging, you need to use:
step
//缩写
s
Function stack frame information
We can use the following command to print function stack frame information
info frame
//缩写
i frame
The output of this instruction is the address of the current function stack frame, the value of the instruction register, the address and value of local variables and other information, which can be compared with the value of the current register and the assembly instruction of the function.
When encountering function nesting, when the program is paused, you can use the following instructions to select the function stack frame:
frame n
Wherein the n
number of layers, the innermost frame function 第0帧
.
Enter the function to debug, what should I do if I suddenly want to exit?
//执行完函数
finish
//不继续往下执行,直接返回
return
//可使用该函数指定返回值
return expression
Since it is debugging, breakpoints must be indispensable
Breakpoint
The easiest way is to breakpoint on the file line number
b linenumber
In addition, we can also set temporary breakpoints
The breakpoint will be deleted after execution
tbreak
//缩写
tb
You can also set conditional breakpoints, it looks like more than IDE
strong:
break … if cond
//例如:
break 5 if i==100
When debugging an assembler or a program without debugging information, it is often necessary to break a point on the program address by:
b *address
So how to get the program entry address?
Get the program entry address
// 非gdb内
strip makebmp
//or
readelf -h makebmp
// 在gdb中也可查看
info files
//or
i files
There is no graphical interface, how to check the breakpoints we set
info breakpoints
//简写
i b
How to delete breakpoints?
// 删除所有断点
delete
// 删除指定断点
delete linenumber
Many IDE
have saved a breakpoint function; gdb
there are, but we need to do it yourself:
//保存已设置的断点
save breakpoints file-name-to-save
//下次调试时可使用以下命令导入断点
source file-name-to-save
The introduction of breakpoints is roughly completed. How to view variables during operation?
- Set watchpoint
View variables
Print string
// 打印ASCII字符串
x/s str
//根据宽字符的长度决定如何打印
//4字节
x/ws
//2字节
x/hs
Print array
// 打印大数组中的内容
print array
//缩写
p array
If you want to print the contents of a large array of default displays up 200
elements
The maximum limit can be set by the following command
set print elements number-of-elements
// 也可通过该指令设置为没有限制
set print elements 0
set print elements unlimited
Print the value of any continuous element in the array
// 其中 index 是数组索引(从0开始计数), num 是连续多少个元素。
p array[index]@num
By default, the index subscript is not printed, which can be turned on by the following command
set print array-indexes on
Print the value of function local variable
//bt是backtrace的缩写
bt ful
bt full n
//从内向外显示n个栈桢,及其局部变量
bt full -n
//从外向内显示n个栈桢,及其局部变量
//如果只是想打印当前函数局部变量的值
info locals
Print memory value
gdb
Use x
commands to print the value of memory in the format x/nfu addr
. Meaning in f
print format from addr
the beginning of the n
length unit of u
the memory value. The specific meanings of the parameters are as follows:
-
n : the number of output units.
-
f : is the output format.
For example, x is output in hexadecimal format;
o is output in octal format, etc...
-
u : indicate the length of a unit
- b is a byte
- h is two bytes (halfword)
- w is four bytes (word)
- g is eight bytes (giantword).
If you want to observe a certain value continuously, this method is very troublesome!
gdb
Provides us with another way that is observation point.
Observation Point
//设置完观察点后,当一个变量值发生变化时,程序会停下来
watch a
//缩写
wa a
//也可以
watch *(data type*)address
It is worth noting that:
The observation point can be implemented in software or hardware, depending on the specific system. However, the observation points implemented by the software will cause the program to run very slowly, so be careful when using it.
If the system supports hardware observation, the following information will be printed when setting the observation point: Hardwarewatchpoint num: expr
How to check the set observation point?
info watchpoints
In addition to setting the observation point at which the value is overwritten, we can also set 读观察点
:
rwatch
//缩写
rw
Note that the rwatch
command only to the hardware viewpoint to take effect
//设置读写观察点
awatch
//缩写
aw
When the behavior of reading a variable or changing the value of a variable occurs, the program will pause
gdb also has a powerful function-assembly
compilation
View assembly code
For example, we can automatically disassemble the code to be executed through the following instructions:
set disassemble-next-line on
start
You can also compare it with the source code
//disas是disassemble命令缩写
disas /m fun
View register
In the debugging process, if you want to view the value of the register, you can use
//i是info命令缩写
i registers
//以上输出不包括浮点寄存器和向量寄存器的内容
//以下指令可输出所有寄存器的内容
i all-registers
//打印单个寄存器的值
i registers regname
//or
p $regname
Modify variables
During the debugging process, can it interfere with the execution of the program, such as temporarily modifying some values?
The answer is yes, the common ones are:
set var variable=expr
//寄存器也可以作为变量值去修改,例如:
set var $eax = 8
//既然如果我们可以修改cp寄存器修改下一帧执行的指令,解锁了奇怪的知识
gdb cannot locate the source file
When we use other program source file, there may be gdb
cases can not locate the source file
This time we will use directory
to set the path to find the source file
directory ../xxxxx
//缩写
dir ../xxx
If you want to gdb
start loading code
position, to avoid each time gdb
Enter the command again, you can
use gdb
the -d
parameters
gdb -q a.out -d /search/code/some
Graphical
The wonderful ones are always saved till the end
图形化启动gdb
gdb -tui projectname
You can also use shortcut keys
Ctrl + X + A
To switch between graphical and character interface
In the graphical interface, the assembly code window can be displayed through the following instructions
layout split
Show register window
//显示通用寄存器
ayout regs
//查看浮点寄存器
tui reg float
//查看系统寄存器
tui reg system
//换回显示通用寄存器内容
tui reg general
hot key
//显示两个窗口
Ctrl + X + 2
//显示一个窗口
Ctrl + X + 1