还不会gdb?看这一篇就够了

2023-11-05

目录

gdb是什么?它有啥威力

gdb常用命令

gdb实战

基本使用

解决coredump!

总结


大家好,我是小李。

今天这一篇博客来跟大家介绍一个非常有用的工具 —— gdb,不管是学习还是工作中,用好gdb,能让你的程序更加丝滑!

gdb是什么?它有啥威力

首先,简单介绍下gdb。gdb的全称是GNU debugger,看名字就知道 gdb 是用来对程序进行 debug 的。

具体来说,gdb有啥用呢?想想这个场景,当我们满心欢喜的写了若干 h 的代码,并且review了好久之后,终于要开始运行了,结果发现输出和预期咋不一样捏?怎么还coredump了捏?当然,有小伙伴会说了,我在可能发生错误的地方用printf把一些可能出错的变量都打出来不就好了吗?这种方式的确也是一种debug 的方式,但是这种方式非常麻烦,对于小程序尚且可以很好地debug,但是对于大型程序来说,这种方式就显得非常“玩具”了。

printf对比于gdb来说:

  • 首先,你可能要加上数不清的 printf 语句,重新编译运行,调试完又得把这些printf语句全部删除,很麻烦;

  • 其次,printf不够灵活,如果我想当某个变量满足一定条件的时候,就让它正常执行,否则单步观察它是怎么影响后续程序的。此时,printf无法达到这样的效果,但是gdb可以。

gdb常用命令

小李相信任何一种工具都是设计者耗费大量精力设计编码出来的,我们作为使用者无法做到面面俱到,完全深入。但是我们能做到的是掌握它的一些常见用法,熟练运用到学习和工作中提升生产效率。

gdb博大精深,但是常用到的命令其实也不多。接下来,小李给大家简单介绍下一些常用命令:

  • 首先,我们在编译的时候要加上 -g 参数,这样编译器才会在生成的 ELF 格式文件中加上一些必要的信息以供gdb进行识别和响应,这是使用gdb的前提;

    gcc -o filename -g filename.c
  • 然后,启用 gdb 进行调试:

    gdb --args filename arglist # 进入调试,并传入参数 arglist
  • start / run —— 在gdb里面让程序跑起来:使用 run 或者 start 命令可以在gdb里面让程序运行起来,其中 start 默认在main函数开头有个断点,让程序在 main 函数开头停下来;而 run 则会在遇到第一个手动设置的断点时才停下来;

  • break —— 强大的断点命令:gdb中最核心的部分之一就是打断点,我们可以使用 break 命令在任意想要让程序停下来的地方打断点,其中断点可以设置为函数名,也可以是指定的代码行:

    b funcName # break可以简写为b,其中funcName是想要断点的函数名,程序执行到funcName的时候会自动停下 
    b lineNum # lineNum是代码行号 
    info b # 查看当前程序的所有断点信息 
    delete bID # 通过 info b 可以查看到断点信息bID,使用delete删除某个断点 
    disable bID # 关闭断点bID 
    enable bID # 开启断点bID tbreak # 设置临时断点
  • next / step —— 让程序往下走“一步”:当程序执行到我们设置断点的地方然后停下来了,这个时候我们想要看看程序接下来是怎么变化的,可以使用 next / step命令。其中step和next都表示让程序单步执行一行代码,但是它们的主要区别在于如果下一行是函数调用的话,step会跳进函数里面继续执行,而next命令则直接执行完这个函数;

    n # next 可以简写为n 
    s # step 可以简写为s
  • finish —— 跳出这个函数:当我们使用step进入某个函数后,通过观察发现这个函数没啥问题,现在想要从这个函数跳出去,而这个函数里面有个循环了若干次的for/while语句,如果使用next命令单步执行到函数末尾的话就有点太慢了。此时可以使用 finish 命令直接执行完这个函数,返回到被调用的地方。

  • watch —— 监视某个变量:我们如果只是想观察程序中某个变量是怎么变化的,那么可以使用 watch 命令,当被观察的值发生变化的时候,程序会自动打印出观察量变化前后的值。

    watch var # 观察变量 var 
    watch (var > 20) # 当var的值大于20的时候,watch才会进行观察
  • backtrace + frame —— 查看调用栈:当我们执行到某个断点时发现了异常值,那么这个异常值是怎么一步一步变成这样的呢?此时可以使用backtrace命令查看函数调用栈,函数调用关系被压在数据结构栈中,当前函数在栈中的下标是 0,调用链往上的函数编号递增;然后搭配 frame 命令可以进入函数调用栈中其他任意函数

    bt # backtrace 可以缩写为 bt 
    frame btID # 使用frame 加上函数在栈中的编号可以跳到调用栈中的某个函数进行观察
  • info —— 强大的查看命令:使用info 命令可以查看局部变量、断点信息、线程信息、寄存器信息等...

    info b 
    info locals 
    info threads 
    info registers
  • quit —— 退出gdb调试

gdb实战

基本使用

掌握了上述基本命令之后,我们可以使用它们的组合进行快乐地 debug 了,一般的流程和组合如下:

  • -g编译

    gcc -o finename -g filename.c
  • --args 带参数gdb:我们可以给执行文件传入参数进行debug

    gdb --args ./filename arg_lists
  • break 设置断点并运行:我们在想要进行观察的函数或者代码行打断点,然后运行程序

    b lineNum run
  • print / bt 查看关键信息:

    print var # 打印想要观察的变量 var 
    bt # 查看函数调用栈,并获取函数在栈中的编号 btId 
    frame btID # 进入调用栈中的函数,继续使用 print 观察

解决coredump!

写代码最怕遇到的是什么?segmentation fault!

一般产生segmentation fault是因为访问了不该被访问的内存地址,此时,linux会在/proc/sys/kernel/core_pattern指定目录下生成一个 coredump 文件,其中包含了产生异常时的进程空间信息。

有同学会说了 “小李啊,我没找到coredump文件啊”,使用 ulimit -c unlimited 设置完再试试捏?然后搭配上面提到的基本命令,就可以快乐地进行错误定位啦!

ulimit -a # 查看系统给core文件配置的大小 
ulimit -c unlimited # 给 core 文件配置无上限,便于生成 coredump 文件 
gdb filename coredump # 对core文件进行gdb 
bt # 查看产生异常时的调用栈关系 
frame btID # 进入调用栈中的某个函数 
info locals # 查看函数的局部变量信息 
up n/ down n # 当前函数栈往前 or 往后几步

总结

以上就是 gdb 的基本使用方法了,掌握了上述基本命令和基本场景使用就能应对学习和工作中的大部分问题了。工具的使用关键在于熟能生巧,希望同学们能多多使用,但也祝大家都能写出没有bug的代码!

 

小李也是在不断地学习与总结中,非常欢迎同学们和小李进行留言交流,大家一起学习进步。

本文将根据工作场景进行持续更新,欢迎同学们关注我呀!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

还不会gdb?看这一篇就够了 的相关文章

  • PHP自学教程之PHP语法基础

    一 PHP5 4的基本语法格式 1 PHP注释与语法标识 1 单行注释 来源于C 的注释 来源于C语言的注释 2 多行注释 来源于C语言的注释 二 PHP5 4的变量与变量的数据类型 变量是由一个美元符 开头 后是一个标识符 标识字符串只字
  • 简单介绍.NET

    1 概要 如果对 NET体系有基础了解的小伙伴可以直接划走 这里主要是分享一些刚学C 编程的小伙伴一些基础知识 刚接触C 或者 NET的小伙伴会对一对专业词汇根本不理解或者不清楚这些东西的作用和关系 例如 NET Native C NET
  • 如何在Delphi里面利用Word的VBA代码进行一些总结

    1 生成VBA代码 Word本身具有很强的可扩展性 尤其是支持用户自定义功能 其实现 的主要方式就是通过VBA代码来实现的 在 工具 gt 宏 gt Visual Basic编辑器 里面就可以看 到具体的宏代码 可以直接进行编辑 而且还可以
  • One-Stage Visual Grounding之一种快速准确的单阶段视觉定位

    One Stage Visual Grounding之一种快速 准确的单阶段视觉定位方法 前言 两阶段框架存在的缺陷 单阶段视觉定位的优点 单阶段视觉定位的方法 视觉和文本特征编码 空间特征编码 融合 定位 一些细节 两阶段与单阶段方法性能
  • 数据结构之顺序表的插入

    题目描述 插入新元素到顺序表 请在程序中建立一个含有10个元素 分别是1 2 3 4 5 6 7 8 9 10的顺序表 然后等候用户输入要插入的元素位序和元素值 如插入成功 输出顺序表的内容 否则输出插入失败 include
  • 八大排序算法-快速排序

    快速排序算法的定义是 通过一趟排序将要排序的数据分割成独立的两部分 其中一部分的所有数据都比另外一部分的所有数据都要小 然后再按此方法对这两部分数据分别进行快速排序 整个排序过程可以递归进行 以此达到整个数据变成有序序列 快速排序算法的基本
  • Unity 性能优化四:UI耗时函数、资源加载、卸载API

    UI耗时函数 1 1 Canvas SendWillRenderCanvases 这个函数是由于自身UI的更新 产生的耗时 1 这里更新的是vertex 属性 比如 color tangent position uv 修改recttrans
  • Python自动抢红包,超详细教程,再也不会错过微信红包了!

    转载自公众号Python多一点 原文链接 Python抢红包 大家好又到了每周六的Python小课堂 今天咱们不说别的 说点有意思的事情 教教大家如何用Python自动抢红包 提到抢红包 就不得不提Xposed框架 它简直是个抢红包的神器
  • c++ 字符串替换指定字符

    这个例子把string字符串中的 替换成 原作者Michael Mrozek 在stackoverflow找到的https stackoverflow com questions 3418231 replace part of a stri
  • 嵌入式开发面试常见问题

    文章目录 0 请问预处理器标识 error的目的是什么 1 嵌入式系统中经常要用到无限循环 如何用C编写死循环 2 程序的局部变量存在于哪里 全局变量存在于哪里 动态申请数据存在于哪里 3 关键字const有什么含义 4 什么是预编译 何时
  • mongdb windows本地进行备份与恢复 也可集成到linux

    1 备份 mongodump h ip 端口 d 备份数据库名称 o 备份路径 示例 mongodump h xxx 27017 u root p test authenticationDatabase admin d test o D t
  • centOS中使用如下命令安装jenkins(详细)

    1 安装jdk wget https download oracle com otn java jdk 8u202 b08 1961070e4c9b4e26a04e7f5a083f551e jdk 8u202 linux x64 tar g
  • VS2017中缺少NuGet 程序包,没有NuGet

    今天装软件的时候 发现我VS2017缺少了NuGet程序包 然后找网上搜索 并没有找到解决步骤 后来去了官网才知道VS2017没有对应网址下载了 已经内嵌在VS2017安装命令台里了 官网在这 https www nuget org dow
  • win10系统开启扫描仪服务器,win10通用扫描仪安装步骤

    win10通用扫描仪安装步骤 为了更加方便地扫描图片文档 很多朋友都会在win10系统电脑中安装扫描仪 不过 最近一些朋友反馈自己在安装之后不知道从哪里打开 让扫描仪开始操作扫描 下面就让小编教我去扫描仪怎么安装吧 扫描仪怎么安装 1 进入
  • ZYNQ之FPGA LED 灯闪烁实验

    一 LED 灯简介 LED灯 又名发光二极管 LED灯工作电流很小 有的仅零点几毫安即可发光 抗冲击和抗震性能好 可靠性高 寿命长 由于这些优点 LED灯被广泛用在仪器仪表中作指示灯 液晶屏背光源等诸多领域 不同材料的发光二极管可以发出红
  • Django 错误之 No module named ‘MySQLdb’

    由于卸载Mysql时将很多相关依赖包都卸载了 重装mysql后启动django出现如下错误 django core exceptions ImproperlyConfigured Error loading MySQLdb module N
  • Linux Shell 之 Shell中的函数调用

    说起函数调用 相信大家也不会陌生 然而对于初学Shell的我来说 Shell中函数调用方式却有点让我不太习惯 自己也走了不少的弯路 因为传递参数时出了一个很 自然 的错误 也让我吃了不少的苦头 所以总结一下Shell中函数的调用方法 一 S
  • linux下设置线程亲和性

    linux下线程亲和性主要就是通过pthread setaffinity np 函数来完成 首先将线程需要绑定的core编号 添加到一个集合中 然后调用此函数就ok 测试代码如下 define GUN SOURCE include
  • 仿真4. 仿真平台架构设计

    背景 1 业务背景 我司对仿真系统的需求日渐增加 比如道路交通的仿真 船舶港口仿真 车联网 ad hoc 仿真 以及运营商承载网的仿真等 2 回顾 什么是仿真时钟 用于描述仿真时间的变化 在连续系统中 仿真时间的变化基于仿真时钟步长的确定
  • 激光三角测距

    激光三角测距原理 1 简介 1 1 Halcon基础 1 2 激光三角法测量系统 2 直射式激光三角测距法 3 斜射式激光三角测距法 3 工作原理 3 1 功能 3 2 普通面阵相机 3 3 线激光的选择 3 4 影响精度的因素 3 5 标

随机推荐

  • Android 禁止输入表情符

    添加过滤器 mEtContent setFilters inputFilters 实现过滤器 private InputFilter inputFilters new InputFilter new InputFilter Pattern
  • MySQL之DQL——查询语言

    前言 今天给大家带来关于数据库查询相关操作 希望各位看官能看个愉快 目录 一 基本概念 1 1 基本概念 1 2 SQL语言的分类 1 3 数据库的存储特点 二 MySQL 2 1 MySQL服务的登录和退出 2 2 MySQL服务的启动和
  • 重磅!Cloud Ace 在班加罗尔和孟买成立新的据点

    Cloud Ace Cooperation 总部位于东京千代田区 Makoto Aoki 总裁 很高兴地宣布 我们已经在班加罗尔建立了新的开发中心 并在孟买建立了新的销售办事处 作为 Cloud Ace 进一步扩大公司在印度业务的努力的一部
  • MySQL之DML

    1 添加数据 语法 insert into 表名 列名1 列名2 列名n values 值1 值2 值n 注意 1 列名和值要一一对应 2 如果表名后 不定义列名 则默认给所有列添加值 insert into 表名 values 值1 值2
  • 关于多线程爬取的加强练习

    多线程能够帮助我们提升爬取爬虫爬取的速度 上一篇文章我们也讲到了如何简单的使用多线程来爬取自己想要要去的东西 今天我们来加强以下 今天我们的目标是多线程爬取股票网站的信息 并保存成文件 本次保存文件的格式为txt 各位想保存别的格式也可以哦
  • 带vector<T>的模板函数

    若两个函数的逻辑相同 但参数类型不同 则可以把这2个函数合并为一个模板函数 有利于精简代码和提高可读性 比如 函数A 将CString的三个动态数组 vector
  • java 使用itextpdf工具实现HTML转PDF文件

    java 使用itextpdf工具实现HTML转PDF文件 本文转载https my oschina net 960823 blog 1588166内容 demo maven依赖包
  • Ubuntu16.04安装ROS时,sudo rosdep init报错,Error: cannot download default sources list from:

    安装ROS时需要安装rosdep 但是由于外网访问不了 所以访问不了https raw githubusercontent com 网站 因此在执行sudo rosdep init这一步时 会提示 如下图 ERROR cannot down
  • LINUX中常用操作命令

    Linux简介及Ubuntu安装 常见指令 系统管理命令 打包压缩相关命令 关机 重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 文件权限管理 大牛笔记 www weixuehao com 来自 http ww
  • 5.1之前, 全局变量存储在_G这个table中, 这样的操作:5.3 lua_setupvalue

    5 1之前 全局变量存储在 G这个table中 这样的操作 a 1 相当于 G a 1 但在5 2之后 引入了 ENV叫做环境 与 G全局变量表产生了一些混淆 需要从原理上做一个理解 在5 2中 操作a 1 相当于 ENV a 1 这是一个
  • 使用ElasticLunr.js进行客户端搜索

    任何博客或文档网站都需要搜索功能 您可以通过多种方式实现这一目标 并且很可能会选择服务器端解决方案 但是 如果您不想处理任何后端 则可以通过lunr js在客户端实现所有后端 几年前 我首次发现Lunr js 但自从我决定使用服务器端选项
  • centos部署openvas

    开放式漏洞评估系统OpenVAS Open Vulnerability Assessment System OpenVAS是开放式漏洞评估系统 也可以说它是一个包含着相关工具的网络扫描器 其核心部件是一个服务器 包括一套网络漏洞测试程序 可
  • 23062C++&QT day2

    封装一个结构体 结构体中包含一个私有数组 用来存放学生的成绩 包含一个私有变量 用来记录学生个数 提供一个公有成员函数 void setNum int num 用于设置学生个数 提供一个公有成员函数 void input 用来对所有学生的成
  • phpstorm如何回滚。并取消本地提交

    1 现在我提交到本地 当前git版本为4b53dca9 上一版本为965cdf14 2 现在执行回滚操作 取消本地提交 版本复制到这里 点击reset就会回滚了 如需使用git命令操作 请参考链接https blog csdn net qq
  • Java 堆排序(大顶堆、小顶堆)

    引用 http lib csdn net article datastructure 8973 堆排序 Heapsort 是指利用堆这种数据结构所设计的一种排序算法 堆积是一个近似完全二叉树的结构 并同时满足堆积的性质 即子结点的键值或索引
  • 欧几里德求最大公约数

    欧几里德求最大公约数也是就辗转相除法 是最基础最简单的算法之一 求最大公约数 int gcd1 int a int b if a lt b swap a b return b 0 a gcd1 b a b int gcd2 int a in
  • 几款国产FPGA系列器件参数汇总

    以下是和厂商确认以及个人在各公司官网上获取的产品参数 部分产品价格可用作参考 价格实时变动 只能作参考 1 高云半导体 FPGA 器件型号 逻辑查找表 RAM资源 I O资源 pll 触发器资源 嵌入式内核 易失性 价格 晨熙系列 GW2A
  • 【并查集】黑魔法师之门

    黑魔法师之门 magician pas c cpp 题目描述 经过了16个工作日的紧张忙碌 未来的人类终于收集到了足够的能源 然而在与Violet星球的战争中 由于Z副官的愚蠢 地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Vio
  • 微信小程序使用web-view引入了vue页面,再从vue页面跳转到微信小程序页面

    在vue项目中引入weixin js sdk插件 npm i weixin js sdk save 在vue组件中引入 import wx from weixin js sdk 跳转微信小程序普通页面 wx miniProgram navi
  • 还不会gdb?看这一篇就够了

    目录 gdb是什么 它有啥威力 gdb常用命令 gdb实战 基本使用 解决coredump 总结 大家好 我是小李 今天这一篇博客来跟大家介绍一个非常有用的工具 gdb 不管是学习还是工作中 用好gdb 能让你的程序更加丝滑 gdb是什么