Linux C++ 开发6 - GDB调试入门指南

2024-09-01 17:28

本文主要是介绍Linux C++ 开发6 - GDB调试入门指南,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 1. GDB的介绍
    • 1.1. 什么是GDB?
    • 1.2. 安装GDB
  • 2. 编译带调试信息的程序
    • 2.1. 命令行编译
    • 2.2. makefile编译
    • 2.3. cmake编译
  • 3. GDB使用流程
    • 3.1. 测试源代码准备
    • 3.2. 启动GDB
    • 3.3. 查看源码
    • 3.4. 运行程序
    • 3.5. 设置断点
    • 3.6. 单步执行
    • 3.7. 查看变量
  • 4. GDB常用命令

与Windows下C++开发相比,Linux下C++开发最大的困难就是程序的调试。

Windows下,Visual Studio系列的IDE(Visual Studio 2010/2013/2015/2017/2019/2022)都内置了C++调试引擎,可通过可视化的界面完成调试操作:在IDE里设置调试断点,然后按F5就可以开始调试了,简单又方便。而且功能强大,支持 断点调试、变量查看、单步执行、堆栈跟踪等等。

Linux就没有这么幸运了,没有这么强大可用的可视化工具。Linux下C++的调试,主要又两种方式:

  • 日志打印: 在代码中通过log打印相关的调试信息,程序运行后分享log的数据进行调试。如果你是开发阶段,或者你的程序是一个简单的Demo,也可以直接用std::cout(C++)或printf(C语言)来打印调试信息。
  • GDB调试: GDB是GNU DeBug的缩写,是Linux的调试器。你需要了解GDB工具的常见用法和调试手段。

本文将带领大家一起入门Linux下GDB的调试方法。

1. GDB的介绍

1.1. 什么是GDB?

GDB的全称是GNU DeBugger,它是一个由GNU项目开发的开源调试器,用于调试C和C++程序。GDB允许开发者检查程序的执行过程,设置断点,查看变量值,以及执行其他调试任务,如分析程序崩溃的原因。

GDB支持多种编程语言,包括C、C++、Objective-C、Fortran、Pascal等。通过GDB,开发者可以更有效地诊断和修复代码中的错误,提高开发效率。

1.2. 安装GDB

《Linux C++ 开发1 - 搭建C++开发环境》一文,我们介绍了Linux C++开发环境的搭建,其中包括了安装GDB的步骤。如果你的系统(Ubuntu)还未安装gdb,可以通过以下命令来安装:

# 安装gdb
sudo apt install gdb
# 检查gdb是否安装成功
gdb --version

2. 编译带调试信息的程序

为了能使用GDB进行调试,需要在编译时包含调试信息(即在编译时能够生成调试符号表symbols)。使用-g-ggdb选项进行编译:

2.1. 命令行编译

# -g选项:生成标准的调试信息
g++ -g -o my_program my_program.cpp
# -ggdb选项:生成gdb专用的调试信息
g++ -ggdb -o my_program my_program.cpp
  • -g 选项用于生成标准的调试信息,这些信息可以被多种调试器使用,该选项生成的调试信息符合DWARF(Debugging With Attributed Record Formats)标准,DWARF这是一种通用的调试信息格式。
  • -ggdb 选项专门为GDB生成调试信息。它生成的调试信息可能包含一些GDB特有的扩展,这些扩展可能不适用于其他调试器,不过使用-ggdb选项可以确保生成的调试信息对GDB是最优的。

2.2. makefile编译

# 构建的最终目标 Iterator(可执行文件)
Iterator:Iterator.o Company.o Person.og++ -o Iterator Iterator.o Company.o Person.o
# 构建目标 Iterator.o
Iterator.o:Iterator.cppg++ -g -c Iterator.cpp
# 构建目标 Company.o
Company.o:Company.cppg++ -g -c Company.cpp
# 构建目标 Person.o
Person.o:Person.cppg++ -g -c Person.cpp# 申明clean为伪目标
.PHONY: clean
clean:rm -f *.o Iterator

注意:

  • 是在编译成目标文件.o的时候加上-g选项,而不是在链接的时候加上-g选项。
  • cpp源代码参见 https://gitee.com/spencer_luo/iterator/tree/master/

2.3. cmake编译

# 设置构建类型: Debug/Release
set(CMAKE_BUILD_TYPE Debug)
# 设置编译选项
if(CMAKE_BUILD_TYPE STREQUAL "Debug")# Debug模式,编译是需要保留调试符号表set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")# Release模式,编译时优化代码,优化选项:-O2set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
endif()

3. GDB使用流程

3.1. 测试源代码准备

demo02.cpp:

#include <iostream>int add(int a, int b)
{return a + b;
}int division(int a, int b)
{return (int)(a / b);
}int main()
{std::string name = "Spencer";std::cout << "Hello, " << name << "!" << std::endl;int a = 5;int b = 0;int c = division(a, b);int d = add(c, 20);std::cout << "d = " << d << std::endl;return 0;
}

Iterator:

参见源码仓库: https://gitee.com/spencer_luo/iterator/tree/cmake/

3.2. 启动GDB

使用以下命令启动GDB并加载要调试的程序:

# 正常启动,program_name为带符号表的可执行程序
gdb program_name
# quiet, 表示不打印gdb版本等信息,界面较为干净;
gdb -q program_name

测试如下:

gdb ./demo02.out 
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 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:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.<http://www.gnu.org/software/gdb/documentation/>.--Type <RET> for more, q to quit, c to continue without paging--<http://www.gnu.org/software/gdb/documentation/>.--Type <RET> for more, q to quit, c to continue without paging--
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./demo02.out...<http://www.gnu.org/software/gdb/documentation/>.<http://www.gnu.org/software/gdb/documentation/>.<http://www.gnu.org/software/gdb/documentation/>.--Type <RET> for more, q to quit, c to continue without paging----Type <RET> for more, q to quit, c to continue without paging--
--Type <RET> for more, q to quit, c to continue without paging--
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./demo02.out...
(gdb)
(gdb) q
gdb -q ./demo02.out
Reading symbols from ./demo02.out...
(gdb)
(gdb) q

3.3. 查看源码

list(缩写l): 查看源程序代码,默认显示10行,按回车键继续看余下的。

file

3.4. 运行程序

run(缩写r) :运行程序直到遇到 结束或者遇到断点等待下一个命令。

file

我们直接运行./demo02.out看到程序崩溃了,但是不知道崩溃在哪一行。但是通过gdb一运行,立马就看出来了。

3.5. 设置断点

break n(缩写b n) :在第n行设置断点。

file

3.6. 单步执行

使用 continue、step、next命令。
在这里插入图片描述

3.7. 查看变量

使用 print、info locals命令。

file

4. GDB常用命令

更多GDB常用命令,将在下一节进行讲解,敬请期待…


大家好,我是陌尘。

IT从业10年+, 北漂过也深漂过,目前暂定居于杭州,未来不知还会飘向何方。

搞了8年C++,也干过2年前端;用Python写过书,也玩过一点PHP,未来还会折腾更多东西,不死不休。

感谢大家的关注,期待与你一起成长。



【SunLogging】
扫码二维码,关注微信公众号,精彩内容

这篇关于Linux C++ 开发6 - GDB调试入门指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1127587

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没