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

相关文章

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get