前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C/C++生态工具链——GDB调试器

C/C++生态工具链——GDB调试器

作者头像
Coder-ZZ
发布2023-02-23 16:47:28
发布2023-02-23 16:47:28
1.8K00
代码可运行
举报
文章被收录于专栏:C/C++进阶专栏C/C++进阶专栏
运行总次数:0
代码可运行

一,GDB简介

GDB全称是GNU symbolic debugger,是Linux平台下最常用的一款调试器。GDB主要用于C/C++开发场景,同时也支持Go、Ada等语言的调试。GDB主要以命令行的形式在shell终端使用,它的一部分底层逻辑借助于ptrace进行实现。GDB的功能很强大,开发者可以在执行时修改函数变量的值以及程序的执行顺序,还可以在程序执行期间查看函数的调用过程、堆栈数据等,也可以利用GDB对代码进行断点调试。

二,两种常见编译模式:Debug模式 & Release模式

Debug模式:

代码在编译时会显示出完整的调试信息以定位问题,编译期间可以查看程序的运行时信息,且编译期间不考虑对代码的执行进行优化。生成的可执行文件执行速度偏慢。

Release模式:

代码在编译时不会显示调试信息,并且编译期间会优化代码的执行。生成的可执行文件执行速度较快。

GDB主要在Debug模式下进行使用。

三,GDB的使用流程

step.1: 开始编译之前,需要配置调试相关的编译命令

a.如果使用gcc/g++编译,需要加入参数“-g"。

b.如果使用cmake编译,需要在CMakeLists.txt中加入:

代码语言:javascript
代码运行次数:0
运行
复制
SET(CMAKE_BUILD_TYPE "Debug")    //选择Debug编译模式
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")  
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

step.2: 编译生成可执行文件以后,利用GDB进入调试模式,常用的方式有如下三种

方式1:gdb [program]

利用gdb在当前目录直接启动可执行程序。

方式2:gdb [program] core

利用gdb同时调试可执行程序和core文件,core是程序非法执行时产生的文件,比如程序core dump后产生的文件。

方式3:gdb [program] [pid]

利用gdb调试服务的一个进程,pid指定了要调试的进程。运行该指令,gdb会以attach的方式进入进程内部开始调试。

step.3: 调试完,退出GDB界面

方式1:在gdb窗口敲下快捷键Ctrl+z

方式2:在gdb窗口输入指令"quit"或"q"

简单使用样例

Demo.cpp:

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;

int findSquare(int a)
{
    return a * a;
}

int main(int n, char** args)
{
    for (int i = 1; i < n; i++)
    {
        int a = atoi(args[i]);
        cout << findSquare(a) << endl;
    }
    return 0;
}

编译 & GDB调试指令:

代码语言:javascript
代码运行次数:0
运行
复制
g++ -g -o demo demo.cpp
gdb ./demo

GDB调试结果:

注:加一个“-tui"参数可以进入GDB的可视化界面,可以很直观地看到自己标注的断点

"gdb ./demo -tui"执行结果:

四,GDB的主要语法

1.查看运行信息的指令

命令全称(命令缩写)

具体含义

show

显示调试器本身的信息

info

显示被调试的程序信息

list

显示源代码

print

打印变量值

display

用法和print类似,但支持自动打印

where

显示当前行号和所在的函数

watch

监控变量或表达式的值

whatis

查看变量的类型

ptype

查看变量的类型

forward-search

从当前行向后查找和正则匹配的行

reverse-search

从当前行向前查找和正则匹配的行

2.调试相关的指令

命令全称(命令缩写)

具体含义

break(b)

设置断点

clear

删除执行到达时的断点

delete

删除所有断点

disable

禁用断点

enable

启用断点

run(r)

一直执行,直到断点或结束

step(s)

执行下一行代码,遇到函数直接进入

next(n)

执行下一行代码,遇到函数不会进入

continue(c)

继续执行直到下一个断点

jump

直接跳到指定位置继续执行

until

和next一样单步执行,常用于循环体中

disass

对函数等进行反汇编

disassemble

对地址进行反汇编

directory(dir)

设置执行路径

set

设定运行的参数

signal

向被调试程序发信号

handle

设置信号对应的操作

3.进程和线程调试相关的指令

命令全称(命令缩写)

具体含义

backtrace(bt)

打印运行到当前位置的堆栈信息

frame

在函数停止的地方,显示当前堆栈

up

向前移动堆栈地址

down

向后移动堆栈地址

atttach pid

运行某个进程

info threads

查看当前线程和id

thread num

切换到num指定的线程

info inferiors

查看当前进程和id

inferior num

切换到num指定的进程

kill inferior num

杀死num指定的进程

set follow-fork-mode parent/child

设置fork后进入父/子进程调试

set detach-on-fork on/off

设置fork时是否同时调试父子进程

set scheduler-locking on/off

设置调试线程时,其他线程是否同步执行

五,GDB使用案例

1.多线程调试

代码样例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

void func(int pid, int ret)
{
    printf("My PID is %d, fork() returned %d\n", pid, ret);

    if (ret)
        printf("We are in the parent process\n");
    else
        printf("We are in the child process\n");
}

int main()
{
    int r = fork();
    func(getpid(), r);
    return 0;
}

调试结果:

查看当前进程:

2.分析程序core dump

a.关于core文件

当执行程序发生core dump时,一般会生成core文件。core文件主要包含了程序运行时的内存、寄存器状态、堆栈指针以及函数堆栈等信息。

b.设置core文件的生成需要使用的命令

代码语言:javascript
代码运行次数:0
运行
复制
1.不生成core文件:

ulimit -c 0

2.生成不限制大小的core文件:

ulimit -c unlimited

3.检查生成core文件的选项是否打开 :

ulimit -a

运行结果:

代码样例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
void foo()
{
    int *ptr = 0;
    *ptr = 7;
}

int main()
{
    foo();
    return 0;
}

运行结果(发生了core dump):

有core文件生成:

开始用GDB分析:

调试命令:

代码语言:javascript
代码运行次数:0
运行
复制
gdb demo core

调试结果:

定位到了让程序崩溃的地方:"*ptr = 7"

查看堆栈信息

六,参考阅读

https://www.tenouk.com/Module000linuxgcc1.html

https://sourceware.org/gdb/onlinedocs/gdb/index.html#SEC_Contents

https://visualgdb.com/gdbreference/commands/set_follow-fork-mode

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员与背包客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档