【给女朋友讲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

相关文章

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快