检查安装gdb
打开终端输入
gdb -v
gdb已安装log:
zx@zx-PC:~/Desktop/codes$ gdb -v
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Ubuntu安装方法:
sudo apt install gdb
Arm平台交叉编译安装(环境限制,还未验证):
1.下载gdb安装包:
wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz
2.解压
tar -xf gdb-7.9.1.tar.xz
3.安装
cd gdb-7.9.1
sudo apt install texinfo
./configure
make
sudo make install
GDB指令
命令 | 简写形式 | 说明 |
---|---|---|
backtrace | bt、where | 显示backtrace |
break | b | 设置断点 |
continue | c、cout | 继续执行 |
delete | d | 删除断点 |
finish | 运行到函数结束 | |
info breakpoints | 显示断点信息 | |
next | n | 执行下一行 |
p | 显示表达式 | |
run | r | 运行程序 |
step | s | 一次执行一行 |
x | 显示内存内容 | |
until | 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 | 执行下一行(以汇编代码为单位) |
print-object | po | 显示目标信息 |
sharelibrary | share | 加载共享符号 |
stepi | si | 执行下一行 |
GDB调试可执行文件
创建测试代码
vim main.c
测试代码:
#include<stdio.h>
#include<stdlib.h>
int main( int argc , char *argv[] )
{
int a = 1;
int i = 0;
int b[3] = {0,1,2};
for(i = 0; i < 3;i++)
b[i] = b[i] + 1;
printf("%d\n",a);
int *p;
p = b;
printf("%d\n",p[0]);
return 0;
}
编译生成可以执行文件
gcc -g -o main main.c # -g表示保留调试参数,否则无法生成调试文件
开始调试
gdb main # gdb载入main可执行文件
查看源码和行号:
(gdb) l
断点:
- 根据行号设置断点
1.(gdb) b 5
2.(gdb) b main.c:5
- 根据函数设置断点
(gdb) b main
- 根据条件设置断点
(gdb) b main.c:10 if a == 1
- 根据偏移量设置断点
(gdb) b +3
- 根据地址设置断点
(gdb) b *0x40059b
- 设置临时断点(只生效一次)
(gdb) tbreak main.c:12
- 显示所有断点
(gdb) info break
- 清除断点
(gdb) delete 2 # 清除第二个断点
(gdb) delete # 清除所有断点
- 清除当前行断点
(gdb) clear
运行:
运行:r
继续单步调试:n
继续执行到下一断点:c
打印变量的值:
- 打印变量
(gdb) p a
- 打印指针
(gdb) p p
- 打印main函数中的变量a
(gdb) p 'main'::a
- 打印指针指向的内容,@后面跟的是打印的长度
(gdb) p *p@2
- 设置变量打印
(gdb) set $abc=0
(gdb) p p[$abc]
- 设置打印格式
x 按十六进制格式显示变量
d 按十进制格式显示变量
u 按十六进制格式显示无符号整型
o 按八进制格式显示变量
t 按二进制格式显示变量
a 按十六进制格式显示变量
c 按字符格式显示变量
f 按浮点数格式显示变量
(gdb) p/x a(按十六进制格式显示变量)
退出GDB:
(gdb) q
gdb原理小结:
gdb调试原理本质是通过设置一个一个断点,可以通过打印输出在这个断点位置所关注变量的值,从而逐个断点调试每个位置的各变量值是否异常,来定位问题出现的位置。
参考文章:
https://blog.csdn.net/lovely_dzh/article/details/109160337