【Linux】GDB调试教程(新手小白)

目录

1. GDB简介

2. GDB安装教程

1)检查机器上是否安装gdb

2) 下载gdb源码包

3) 解压gdb源码包

4) 安装

5) 检查是否安装成功

3. GDB入门操作

1)创建测试代码

2)启动gdb

3)断点

4)运行

5)打印变量的的值

6)退出gdb

参考文章

 


1. GDB简介

GDB,全称 GNU symbolic debugger,简称 GDB调试器,是 Linux 平台下最常用的一款程序调试器

2. GDB安装教程

CentOSx下安装GDB

1)检查机器上是否安装gdb

rpm -qa | grep gdb

[root@]# rpm -qa | grep gdb
gdbm-1.10-8.el7.x86_64
gdbm-devel-1.10-8.el7.x86_64

若安装,则采用以下命令卸载

rpm -e --nodeps [软件版本]

[root@]# rpm -e --nodeps gdbm-1.10-8.el7.x86_64
[root@]# rpm -e --nodeps gdbm-devel-1.10-8.el7.x86_64

2) 下载gdb源码包

wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz

[root@]# wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz
--2020-10-19 15:05:39--  http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz
Resolving mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)... 202.141.176.110, 218.104.71.170, 2001:da8:d800:95::110
Connecting to mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)|202.141.176.110|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17867692 (17M) [application/octet-stream]
Saving to: ‘gdb-7.9.1.tar.xz’

100%[====================================================================================================================================================>] 17,867,692  36.5MB/s   in 0.5s   

2020-10-19 15:05:39 (36.5 MB/s) - ‘gdb-7.9.1.tar.xz’ saved [17867692/17867692]

3) 解压gdb源码包

tar -xf gdb-7.9.1.tar.xz

[root@]# tar -xf gdb-7.9.1.tar.xz

4) 安装

cd gdb-7.9.1

sudo yum install texinfo

./configure

make

sudo make install

[root@]# cd gdb-7.9.1
[root@]# sudo yum install texinfo
.
.
.
Dependency Installed:
  perl-Text-Unidecode.noarch 0:0.04-20.el7          perl-libintl.x86_64 0:1.20-12.el7         

Complete!
[root@]# ./configure
.
.
.
configure: creating ./config.status
config.status: creating Makefile
[root@]# make
.
.
.
make[1]: Nothing to be done for `all-target'.
make[1]: Leaving directory `/root/.vimplus/gdb-7.9.1'
[root@]# make install
.
.
.
make[1]: Nothing to be done for `install-target'.
make[1]: Leaving directory `/root/.vimplus/gdb-7.9.1'

5) 检查是否安装成功

gdb -v

[root@]# gdb -v
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 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-unknown-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".

3. GDB入门操作

命令               简写形式         说明
backtrace          bt、where       显示backtrace
break              b               设置断点
continue           c、cont         继续执行
delete             d               删除断点
finish                             运行到函数结束
info breakpoints                   显示断点信息
next               n               执行下一行
print              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             执行下一行

1)创建测试代码

vim test.c

gcc -g -o test.exe test.c

关于vim/vi的用法这里不再概述,推荐vim的配置程序vimplus

写完代码后,gcc编译代码(PS. 如果gcc编译的时候没有加上-g参数,那么就不会保留调试参数,就不能用gdb调试)

测试代码如下:

#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;
}

2)启动gdb

       在 Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件,Linux 系统所具备的这种功能又称为核心转储(core dump)。幸运的是,GDB 对 core 文件的分析和调试提供有非常强大的功能支持,当程序发生异常崩溃时,通过 GDB 调试产生的 core 文件,往往可以更快速的解决问题。

  • 查看是否开启 core dump 这一功能

ulimit -a

[root@]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7284
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7284
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

如果 core file size(core 文件大小)对应的值为 0,表示当前系统未开启 core dump 功能

  • 开启 core dump

ulimit -c unlimited

[root@]# ulimit -c unlimited
[root@]# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7284
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7284
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

unlimited 表示不限制 core 文件的大小

测试代码:

1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5     char *p = NULL;                                                                    
  6     *p = 123;
  7     return 0;
  8 }

测试结果:

[root@]# vim main.c
[root@]# gcc -g -o main.exe main.c
[root@]# ls
main.c  main.exe  test.c  test.exe
[root@]# ./main.exe
Segmentation fault (core dumped)
[root@]# ls
core.17313  main.c  main.exe  test.c  test.exe

测试代码中,发生内存访问错误,程序崩溃,崩溃信息存入core.17313文件中

  • 启动gdb

gdb test.exe

[root@]# gdb test.exe
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 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-unknown-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"...
Reading symbols from test.exe...done.
(gdb)_

3)断点

  • 根据行号设置断点

第一种  (gdb) b 5 

第二种  (gdb) b test.c:5

  • 根据函数设置断点

(gdb) b main

  • 根据条件设置断点

(gdb) b test.c:10 if a == 1

  • 根据偏移量设置断点

(gdb) b +12

  • 根据地址设置断点

(gdb) b *0x40059b

  • 设置临时断点

临时断点只生效一次

(gdb) tbreak test.c:12

(gdb) b test.c:5
Breakpoint 1 at 0x40053c: file test.c, line 5.
(gdb) b main
Note: breakpoint 1 also set at pc 0x40053c.
Breakpoint 2 at 0x40053c: file test.c, line 6.
(gdb) b test.c:10 if a == 1
Breakpoint 3 at 0x400568: file test.c, line 10.
(gdb) b +12
Breakpoint 4 at 0x40059b: file test.c, line 13.
(gdb) b *0x40059b
Note: breakpoint 4 also set at pc 0x40059b.
Breakpoint 5 at 0x40059b: file test.c, line 13.
(gdb) tbreak test.c:12
Note: breakpoints 4 and 5 also set at pc 0x40059b.
Temporary breakpoint 6 at 0x40059b: file test.c, line 12.
  • 显示所有断点

(gdb) info break

(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040053c in main at test.c:5
2       breakpoint     keep y   0x000000000040053c in main at test.c:6
3       breakpoint     keep y   0x0000000000400568 in main at test.c:10
        stop only if a == 1
4       breakpoint     keep y   0x000000000040059b in main at test.c:13
5       breakpoint     keep y   0x000000000040059b in main at test.c:13
6       breakpoint     del  y   0x000000000040059b in main at test.c:12
  • 清除断点

清除某个断点 (gdb) delete 4

清除所有断点 (gdb) delete 

(gdb) delete 4
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) info break
No breakpoints or watchpoints.

清除当前行断点  (gdb) clear

Breakpoint 3, main (argc=1, argv=0x7fffffffe508) at test.c:13
13          p = b;
(gdb) clear
Deleted breakpoint 3 

4)运行

  • 运行和继续

运行 r

继续单步调试 n

继续执行到下一个断点 c

  • 查看源码和行号

l

(gdb) l
1       #include <stdio.h>
2       #include <stdlib.h>
3
4       int main( int argc, char *argv[])
5       {
6           int a = 1;
7           int i = 0;
8           int b[3] = {0, 1, 2};
9           for (i = 0; i < 3; i++)
10              b[i] = b[i] + 1;
(gdb) l
11          printf("%d\n", a);
12          int *p;
13          p = b;
14          printf("%d\n", p[0]);
15          return 0;
16      }
(gdb) l
Line number 17 out of range; test.c has 16 lines.

5)打印变量的的值

  • 打印变量

p a

  • 打印指针

p p

  • 打印main函数中的变量a

p 'main'::a

  • 打印指针指向的内容,@后面跟的是打印的长度

p *p@3

(gdb) run
Starting program: /root/daizhh/test.exe 

Breakpoint 1, main (argc=1, argv=0x7fffffffe508) at test.c:11
11          printf("%d\n", a);
(gdb) p a
$1 = 1
(gdb) p b
$2 = {1, 2, 3}
(gdb) n
1
13          p = b;
(gdb) c
Continuing.

Breakpoint 2, main (argc=1, argv=0x7fffffffe508) at test.c:14
14          printf("%d\n", p[0]);
(gdb) p p
$3 = (int *) 0x7fffffffe400
(gdb) p 'main'::a
$4 = 1
(gdb) p *p@3
$5 = {1, 2, 3}
  • 设置变量打印

set $index = 0

p p[$index]

(gdb) set $index = 0
(gdb) p p[$index]
$6 = 1
  • 设置打印格式
  1. x 按十六进制格式显示变量
  2. d 按十进制格式显示变量
  3. u 按十六进制格式显示无符号整型
  4. o 按八进制格式显示变量
  5. t 按二进制格式显示变量
  6. a 按十六进制格式显示变量
  7. c 按字符格式显示变量
  8. f 按浮点数格式显示变量

(gdb) p/x a(按十六进制格式显示变量)

(gdb) p/x a
$7 = 0x1

6)退出gdb

q


参考文章

http://c.biancheng.net/gdb/

https://blog.csdn.net/wh_computers/article/details/94618240

https://blog.csdn.net/andrewgithub/article/details/88210949

  • 70
    点赞
  • 219
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值