【给女朋友讲C++】C++的调试之gdb

2024-08-29 23:20
文章标签 c++ 调试 gdb 女朋友

本文主要是介绍【给女朋友讲C++】C++的调试之gdb,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1 什么是gdb
  • 2 core dump
    • 2.1 打开core dump功能
    • 2.2 修改core dump文件保存的路径
    • 2.3 使用gdb分析core文件
  • 3 gdb常用命令
    • 3.1 为了更好的使用gdb调试,需要设置-g编译选项
      • 3.1.1 命令行方式编译:
      • 3.1.2 cmake方式
    • 3.2 gdb的help
    • 3.3 gdb与可执行程序相关的命令
      • 3.3.1 可执行程序未执行
      • 3.3.2 可执行程序已经执行
    • 3.4 gdb基础命令
  • 4 参考

1 什么是gdb

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果是在windows上使用vs调试也是不错的选择。

工作中一般都是用gdb来分析core dump文件的多,如果core dump文件分析不出来,再用gdb单步执行进行分析。对于程序的逻辑和算法一般用log会更为直观一些,当然也会gdb + log来联合分析问题。

2 core dump

当程序在运行过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫core dump。 我们可以认为core dump是”内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时dump下来, 例如寄存器信息(包括程序指针,栈指针等),内存管理信息,其他处理器和操作系统状态和信息。

2.1 打开core dump功能

  • 在终端中输入命令 ulimit -c,输出结果为0,说明默认是关闭core dump的,即当程序异常终止时,也不会生成core dump文件;
  • 我们可以使用命令 ulimit -c unlimited 来开启core dump功能;
  • 如果想需要永久生效,可以修改文件/etc/security/limits.conf文件,在其中增加一行:
# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain>       <type>  <item>  <value>*             soft    core    unlimited

2.2 修改core dump文件保存的路径

  • 默认生成的core dump文件保存在可执行文件所在的目录,文件名为core
  • 通过修改 /proc/sys/kernel/core_uses_pid 文件可以控制生成core文件名时是否自动加上pid号;
    • 例如,echo 1 > /proc/sys/kernel/core_used_pid,生成的core文件名将会变成core.pid,其中pid表示该进程的PID;
  • 还可以通过修改**/proc/sys/kernel/core_pattern**来控制生成core文件保存的位置以及文件格式;
    • 例如,可以用echo “/tmp/corefile-%e-%p-%t” > /proc/sys/kernel/core_pattern设置生成的core文件保存在/tmp/corefile目录下,文件名格式为core-命令名-pid-时间戳。

2.3 使用gdb分析core文件

使用如下命令打开core文件

gdb [exec file] [core file]

然后执行bt命令查看堆栈,一般就可以根据提示看出来问题,因为往往都是非法访问内存。如果不行,就需要使用更多的gdb命令,下面介绍。

3 gdb常用命令

3.1 为了更好的使用gdb调试,需要设置-g编译选项

为了更好的使用gdb调试程序,在使用gcc/g++编译器的时候需要加上**-g**参数。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。

3.1.1 命令行方式编译:

g++ -g -o test test.cpp

3.1.2 cmake方式

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

3.2 gdb的help

$ gdb
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 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".
(gdb) help
List of classes of commands:aliases -- Aliases of other commands.
breakpoints -- Making program stop at certain points.
data -- Examining data.
files -- Specifying and examining files.
internals -- Maintenance commands.
obscure -- Obscure features.
running -- Running the program.
stack -- Examining the stack.
status -- Status inquiries.
support -- Support facilities.
tracepoints -- Tracing of program execution without stopping the program.
user-defined -- User-defined commands.Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
  • gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help
    命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help 来查看命令的帮助。
  • gdb中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命令的前几个字符应该要标志着一
    个唯一的命令,在Linux下,你可以敲击两次TAB键来补齐命令的全称,如果有重复的,那么gdb会把其例出来。

3.3 gdb与可执行程序相关的命令

3.3.1 可执行程序未执行

gdb <program>        # rogram也就是你的执行文件
gdb --args <program> arg1 arg2 arg3  # arg1,arg2,arg3为命令行参数
gdb <program> core   # core是程序非法执行后core dump后产生的文件

在以gdb 等方式启动gdb后,gdb会在PATH路径和当前目录中搜索的源文件。如要确认gdb是否读到源文
件,可使用l或list命令,看看gdb是否能列出源代码。

  1. 也可以在gdb启动后设置命令行参数
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。
  1. 运行环境
path <dir> 可设定程序的运行路径。
show paths 查看程序的运行路径。
set environment varname [=value] 设置环境变量。如:set env USER=hchen
show environment [varname] 查看环境变量。
  1. 工作路径
cd <dir> 相当于shell的cd命令。
pwd 显示当前的所在目录。
  1. 程序的输入输出
run > outfile   # 运行程序,将输出重定向到outfile

3.3.2 可执行程序已经执行

gdb <program> <PID>  # 如果你的程序已经启动,那么你可以指定这个程序运行时的进程ID,gdb会自动attach上去,并调试他。# 另一种方式:先用gdb <program>关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程的PID。并用detach来取消挂接的进
程。

3.4 gdb基础命令

r   # 等于run,运行程序
b   # 等于break,设置断点# 可选的参数有:# 方法名,如C++中可以使用class::function或function(type,type)格式来指定函数名。或者filename:function# 行号,如filename:linenum
info break # 查看断点
clear # 清除所有的断点,只是让断点失效,还会保留其他相关信息。# 可选的参数有:方法名,行号,断点号
delete [breakpoints] [range...]  # 删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。
disable [breakpoints] [range...]  # disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。简写命令是dis
enable [breakpoints] [range...]  # enable所指定的停止点,breakpoints为停止点号。
c   # 等于continue,恢复程序运行,直到结束
s   # 等于step,单步执行程序,遇到函数,会进入函数
n   # 等于next,和step的不同时,遇到函数不会进入
finish  # 运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息
bt       # 等于backtrace,查看堆栈信息
f <n>    # 等于frame <n>,查看某一层的堆栈信息
up <n>   # 表示向栈的上面移动n层,可以不打n,表示向上移动一层。 
down <n> # 表示向栈的下面移动n层,可以不打n,表示向下移动一层。
info f   # 等于info frame,这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等
list  # 显示当前行后面的源程序。可选的参数有行号,方法名
dir <dirname ... >  # 等于directory <dirname ... >, 加一个源文件路径到当前路径的前面。如果你要指定多个路径,UNIX下你可以使用“:”,Windows下你可以使用“;”
directory  # 清除所有的自定义的源文件搜索路径信息。
show directories # 显示定义了的源文件搜索路径。
p    # 等于print, 可以打印变量,表达式的值

4 参考

  1. Linux下core dump
  2. GDB完全中文手册.pdf
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

这篇关于【给女朋友讲C++】C++的调试之gdb的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建