gdb 教程

news2024/9/21 16:33:59

文章目录

  • GDB
    • 启动 GDB 的方法
    • GDB 命令
    • 工具
    • 参考

GDB

GDB是Linux下的调试工具,可以调试C、C++、Go、java等语言

GDB提供了以下四个功能:

  • 程序启动时,可以按照自定义的要求运行程序,如设置参数和环境变量
  • 可以让被调试的程序在所指定的代码处暂停运行,并查看当前运行状态(如当前变量的值,函数的执行结果),即支持断点调试
  • 当程序被停止时,可以查看当前程序中的变量的状态
  • 在程序执行过程中,可以改变某个变量的值,还可改变代码的执行顺序

要使用gdb调试,必须在源代码生成二进制程序的时候,加上 -g 选项,release 模式,如果没有 -g ,将看不见程序的函数名、变量名,所替代的全是运行时的内存地址

可以通过 readelf -S 可执行文件 | grep debugfile 可执行文件 查看某个二进制文件有没有调试信息,如下红色框是调试信息

在这里插入图片描述

启动 GDB 的方法

  • gdb program:调式方式启动运行无参程序

  • gdb program core:用 GDB 同时调试一个运行程序和 core 文件,core 是程序非法执行后 core dump 后产生的文件

    # 查看 limit
    (base) china@china:~$ ulimit -c
    0
    (base) china@china:~$ ulimit -a
    real-time non-blocking time  (microseconds, -R) unlimited
    core file size              (blocks, -c) 0
    data seg size               (kbytes, -d) unlimited
    scheduling priority                 (-e) 0
    file size                   (blocks, -f) unlimited
    pending signals                     (-i) 127327
    max locked memory           (kbytes, -l) 4084144
    max memory size             (kbytes, -m) unlimited
    open files                          (-n) 1024
    pipe size                (512 bytes, -p) 8
    POSIX message queues         (bytes, -q) 819200
    real-time priority                  (-r) 0
    stack size                  (kbytes, -s) 8192
    cpu time                   (seconds, -t) unlimited
    max user processes                  (-u) 127327
    virtual memory              (kbytes, -v) unlimited
    file locks                          (-x) unlimited
    # 修改为不限制 core 文件大小
    (base) china@china:~$ ulimit -c unlimited
    (base) china@china:~$ ulimit -c
    unlimited
    
  • gdb program process_id:指定程序运行时的进程 ID,GDB 会自动 attach 上去,并调试,program 应该在 PATH 环境变量中搜索得到

    # 修改 /etc/sysctl.d/10-ptrace.conf
    kernel.yama.ptrace_scope = 0
    
    # 调试
    (base) china@china:~/thread-pool$ ps -ef | grep program_name
    china      53735   48756  0 20:32 pts/0    00:00:00 ./program_name
    (base) china@china:~/thread-pool$ sudo gdb program_name -p 53735
    

GDB 启动时常用参数

# 从指定文件中读取符号表
--symbols=SYMFILE

# 从指定文件中读取符号信息,并把它用在可执行文件中
--se=FILE

# 调试时 core dump 的 core 文件
--core=COREFILE

# 加入一个源文件的搜索路径,默认搜索路径是环境变量中 PATH 所定义的路径
--directory=DIR

调式core文件,段错误

# 查看
ulimit -a
ulimit -c
# 设置
ulimit -c unlimited

# 设置core生成目录为/data/coredump,默认当前目录下,%e表示程序名,%p表示进程id
echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern

当程序core dump时,可能会产生core文件,它能够很大程序帮助我们定位问题。但前提是系统没有限制core文件的产生。

ulimit -a

ulimit -c

ulimit -c unlimited # 此时会产生core文件

gdb 程序文件名 core文件名

调试core文件,需要设置ulimit -c unlimited,并设置core文件生成目录
当程序运行错误结束的时候,会自动生成一个core文件,gdb ./main core

GDB 命令

在这里插入图片描述

  • help

    # help 命令仅显示 GDB 命令种类
    (gdb) help
    # 查看 breakpoints 的所有命令
    (gdb) help breakpoints 
    
  • breakpoint:设置断点

    # 
    (gdb) braek function_name
    
    # 
    (gdb) break line_num
    
    # 在当前行号的前 offset 
    (gdb) break +offset
    
    # 在当前行号的后 offset
    (gdb) break -offset
    
    (gdb) break file_name:line_num
    
    (gdb) break file_name:function_name
    
    # 在程序运行的内存地址处
    (gdb) break *address
    
    # 如果 cond 成立
    (gdb) break …… if cond
    
    # 在下一条指令处停住
    (gdb) break
    
    # 查看断点,[n]表示断点号
    (gdb) info breakpoints [n]
    
  • watchpoint:设置观察点

    # 一旦 expr 值变化,程序停止
    (gdb) watch expr
    
    # 一旦 expr 被读时,程序停止
    (gdb) rwatch expr
    
    # 当 expr 被读或写,程序停止
    (gdb) awatch expr
    
    # 查看
    (gdb) info watchpoints
    
  • catchpoint:设置捕捉点,捕捉程序运行时的一些时间

    # 抛出的异常
    (gdb) catch throw
    
    # 捕获的异常
    (gdb) catch catch
    
    # 调用系统调用 exec 时
    (gdb) catch exec
    
    # 调用系统调用 fork 时
    (gdb) catch fork
    
    # 调用系统调用 vfork 时
    (gdb) catch vfork
    
    # load 或 load 载入共享库时
    (gdb) catch load
    
    # 卸载共享库时
    (gdb) catch unload
    
    # 只设置一次捕捉点,当程序停止后,自动删除
    (gdb) tcatch
    
  • 维护停止点:delete、clear、disable、enable

    # 清除所有已定义的停止点
    (gdb) clear
    
    # 
    (gdb) clear function_name
    
    # 
    (gdb) clear line_num
    
    # 删除所有的断点
    (gdb) delete
    
    # 删除指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) delete [breakpoints] [range...]
    
    # 关闭所有的断点
    (gdb) disable
    
    # 关闭指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) disable [breakpoints] [range...]
    
    # 开启所有的断点
    (gdb) enable
    
    # 开启指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) enable [breakpoints] [range...]
    
  • run

    # 
    (gdb) set args ...
    
    # 运行程序,直到程序结束或下一个断点
    (gdb) run args
    
    # 恢复程序运行,直到结束或者下一个断点
    (gdb) continue
    
    # 单步,会进入函数
    (gdb) setp
    
    # 单步,不会进入函数
    (gdb) next
    
    # 运行程序,直到当前函数完成返回,打印函数返回时的堆栈地址和返回值及参数值等信息
    (gdb) finish
    
    # 运行程序直到退出循环体
    (gdb) until
    
  • quit

    (gdb) quit
    
  • shell

    # shell command
    (gdb) shell pwd
    
    # 查看运行环境
    (gdb) path
    (gdb) show path
    
    # 
    (gdb) cd
    
    # 查看当前目录
    (gdb) pwd
    
  • log

    set logging on 打开日志功能
    	默认在当前目录生成gdb.txt
    

工具

  • readelf

    root@china:~/csapp# readelf -S ./main | grep debug
      [28] .debug_aranges    PROGBITS         0000000000000000  00003036
      [29] .debug_info       PROGBITS         0000000000000000  00003066
      [30] .debug_abbrev     PROGBITS         0000000000000000  000031af
      [31] .debug_line       PROGBITS         0000000000000000  00003295
      [32] .debug_str        PROGBITS         0000000000000000  00003321
      [33] .debug_line_str   PROGBITS         0000000000000000  0000341a
    
  • file

    root@china:~/csapp# file ./main
    ./main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fa5fb837d07c13549e0880c95a0e6ea0c5e54f57, for GNU/Linux 3.2.0, with debug_info, not stripped
    

参考

  • man gdb

  • GDB调试还不会?看这篇就够了!-腾讯云开发者社区-腾讯云 (tencent.com)

  • 【Linux】GDB用法详解(5小时快速教程) - Avatarx - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092508.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netflix Feign:微服务HTTP调用如何简化?

Netflix Feign:微服务HTTP调用如何简化? 1、什么是Netflix Feign?2、Feign的优点3、示例4、总结 💖The Begin💖点点关注,收藏不迷路💖 1、什么是Netflix Feign? Feign是一个声明式的…

MFC工控项目实例之十添加系统测试对话框

承接专栏《MFC工控项目实例之九选择下拉菜单主界面文本框显示菜单名》 参考前期我的博客文章《MFC3d立体按钮制作》 这里只给出相关代码 1、在SysTest.h文件中添加代码 #include "ShadeButtonST.h" #include "BtnST.h" class CSysTest : public CDialog {…

OpenAI“草莓”模型及全能型与专业型AI的思考

一、OpenAI“草莓”模型的全能性及其未来趋势 近日,OpenAI预计在秋季推出的代号为“草莓”的新AI模型,展现了其在自然语言处理(NLP)和深度学习领域的又一重大突破。该模型不仅增强了推理能力,还提供了更为人性化的互动…

穿越Java世界的继承奇旅:从基类到子类的华丽蜕变

1.为什么要继承 2.什么是继承以及继承的方式 3.继承的一些语法 4.父类成员的访问 5.关键字super 6.关键字protected 7.关键字final 8.继承与组合 一:为什么要继承 ①代码重用:继承允许我们重用、扩展或修改父类的属性和方法,而无需重…

<Rust>egui学习之小部件(四):如何在窗口中添加滚动条Scroll部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析,主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统:windows 平台:visual studio code 语言:rust 库:egui、eframe 概述 本文是本专栏的第四篇博…

【C++ Primer Plus习题】7.10

问题: 解答: #include <iostream> using namespace std;double add(double a, double b) {return a b; }double mul(double a, double b) {return a * b; }double sub(double a, double b) {return a - b; }double div(double a, double b) {return a / b; }double cal…

[LLM]:大模型(Transformer)参数量分析

1. 前言2. 模型参数量 文章内容主要摘自&#xff1a;https://zhuanlan.zhihu.com/p/624740065 1. 前言 最近&#xff0c;OpenAI推出的ChatGPT展现出了卓越的性能&#xff0c;引发了大语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面&am…

Python编码系列—Python代码重构:提升代码质量

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

Leetcode面试经典150题-151.反转字符串中的单词

class Solution {public String reverseWords(String s) {/**先trim一下去掉前后的空格*/String str s.trim();/**转成字符数组 */char[] sArr str.toCharArray();/**先整体倒置*/int l 0;int r sArr.length - 1;reverse(sArr, l, r);/**然后每个单词中逆序 */int left 0;…

SAM 提示框和 Unet的语义分割的融合:自动驾驶车道线分割

1、前言 最近SAM 模型复现的多了&#xff0c;看了不少官方的源码&#xff0c;尝试下SAM和Unet的结合 SAM的提示分割&#xff0c;其实就是在分割的时候&#xff0c;为数据增加一个提示信息&#xff0c;可以是框&#xff0c;点&#xff0c;或者文本等等。这样大模型网络就可以根…

【Python】简单的爬虫抓取

效果&#xff1a;抓取某个学校网站的教授名录&#xff0c;并获取研究方向。 由于网站使用的都是明文&#xff0c;所以抓起来没什么难度&#xff0c;且平时访问量小&#xff0c;很值得用来练习。 代码如下&#xff0c;解释请见注释 import timeimport requests from bs4 impor…

RN开发问题

1、滚动项定位错误 ERROR Invariant Violation: scrollToIndex should be used in conjunction with getItemLayout or onScrollToIndexFailed, otherwise there is no way to know the location of offscreen indices or handle failures. 原因&#xff1a;已修复&#xff0c…

求一个使用C语言将重力加速度gx,gy,gz积分获取到速度的代码

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (一) 依赖库编译、第三方库编译安装

目录 1 jetson-ffmpeg的编译安装与配置--用来做视频编码、视频解码 2 CV-CUDA库的编译安装与配置--用来做图像缩放、裁剪、色域转换 3 cuda cudnn TensorRT相关库的拷贝与配置 3.1将cuda cudnn TensorRT相关的头文件拷贝到工程中 3.2 将cuda cudnn TensorRT相关的库拷贝到…

docker实战基础一

一、docker安装 # step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装 Doc…

FlowUs:强大图表功能与多维表结合,开启便捷办公新时代

在当今数字化办公的浪潮中&#xff0c;我们一直在寻找一款能够高效整合数据、清晰呈现信息的工具。而 FlowUs 以其强大的图表功能结合多维表的能力&#xff0c;为我们带来了前所未有的便捷体验。 一、多维表&#xff1a;数据管理的强大基石 FlowUs 的多维表功能就像是一个数据魔…

016_Save_the_picture_in_Matlab中保存图片

图片文件 Matlab核心功能包括出图&#xff0c;印刷质量的图片输出是Matlab核心竞争力之一&#xff0c;matplotlib疯狂追赶&#xff0c;但还是差距明显。出图的含义就是&#xff1a;打印或者导出图形窗体的内容&#xff0c;可供后续使用。在Matlab中&#xff0c;这个行为被定义…

弗洛伊德(Floyd)算法(C/C++)

弗洛伊德算法&#xff08;Floyds algorithm&#xff09;&#xff0c;又称为弗洛伊德-沃尔什算法&#xff08;Floyd-Warshall algorithm&#xff09;&#xff0c;是一种用于在加权图中找到所有顶点对之间最短路径的算法。这个算法适用于有向图和无向图&#xff0c;并且可以处理负…

[YM]课设-C#-WebApi-Vue-员工管理系统 (五)登录

分析&#xff1a; 请求路径&#xff1a;/login 请求方式&#xff1a;POST 接口描述&#xff1a;该接口用于员工登录Tlias智能学习辅助系统&#xff0c;登录完毕后&#xff0c;系统下发JWT令牌。 > api文档中提到JWT令牌 这个相对来说比较复杂 是用来加密&#xff0c;…

那些生意好的厂家如何找到目标客户呢?

寻找并精准定位目标客户是任何一家追求持续发展与业务增长的厂家必须掌握的关键技能。那些生意兴隆的厂家之所以能够脱颖而出&#xff0c;很大程度上得益于他们高效且精准的客户寻找策略。今天&#xff0c;我们将深入探讨这些成功厂家如何精准找到并吸引目标客户。 01明确目标…