当前位置: 首页 > news >正文

调试排查工具介绍(gdb、strace、Valgrind等)

1.GDB用户态调试 /KGDB内核级调试

使用GDB调试之前,需要用-g选项编译程序,这样可执行文件中才会包含符号表(变量名、函数名、行号等信息)g++ -g -o myprogram myprogram.cpp

#步骤1:启动GDB并设置断点,(delete是删断点) gdb ./test (gdb) break main # 在main函数入口打断点 (gdb) break 25 # 在源文件第25行打断点 (gdb) break func1 if x==100 # 条件断点:x等于100时才触发 (gdb) info breakpoints # 查看所有断点 # 步骤2:运行程序 (gdb) run # 开始运行,直到遇到断点 (gdb) run arg1 arg2 # 带命令行参数运行 (gdb) run < input.txt # 重定向标准输入 # 步骤3:当程序停在断点时,单步执行与继续 (gdb) next # n,单步执行,不进入函数内部 (gdb) step # s,单步执行,会进入函数内部 (gdb) continue # c,继续运行,直到下一个断点或程序结束 (gdb) finish # 执行完当前函数并返回(跳出函数) (gdb) until 30 # 运行到第30行(用于跳出循环) # 步骤4:查看状态 (gdb) print var # 打印变量var的值 (gdb) display var # 每次暂停时自动打印var的值 (gdb) info locals # 查看当前函数的所有局部变量 (gdb) info registers # 查看寄存器内容 (gdb) backtrace # bt,查看函数调用栈(崩溃时最常用) (gdb) list # 显示当前执行的源代码 (gdb) disas # 显示汇编代码 # 步骤5:修改变量(调试时临时改变行为) (gdb) set var x=100 # 将变量x的值改为100 (gdb) call func2() # 手动调用函数func2

举例:

段错误 (core dumped) : SIGSEGV 信号,错误码编号为 11。是由于程序尝试访问不存在的内存区域引发的。

常见原因如下:

  • 访问未初始化的指针(空指针解引用),ptr 未指向合法内存(如未通过new 分配内存)。

  • 数组越界访问

  • 释放后使用内存

  • 栈溢出。递归过深或局部变量占用过多栈空间。

如何定位和解决?

运行 GDB执行程序,查看堆栈信息:(gdb) bt(Backtrace)定位错误位置。

利用gdb调试器跟踪调用栈

使用gdb,在程序崩溃时查看调用栈(bt命令),定位最后执行的函数,检查该函数中是否有异常内存操作。若栈溢出,调用栈会显示递归层数过深的函数;若堆溢出,可能指向new/malloc的异常调用。

Core Dump文件是程序崩溃时的内存快照,包含虚拟内存布局、寄存器状态、调用栈等信息。

具体实现:

  • 解析 Core Dump 中的 “程序头” 获取内存段信息(代码段、数据段、堆、栈的地址范围);

  • 从栈内存中提取调用栈(函数返回地址),映射到源代码的行号;

  • 查看堆内存中的对象状态(如通过print查看指针指向的内存内容),判断是否有异常分配(如超大对象)。

2. strace /ftrace / ltrace / ptrace/bpftrace 等,或使用trace-cmd工具

  • ptrace:Linux 的系统调用接口(API),供调试/跟踪进程使用。

  • strace:基于 ptrace,跟踪进程执行时的 系统调用 和 接收到的信号。是排查线上故障(如文件打不开、权限错误、网络连接失败等)的首选工具。

  • ltrace:跟踪用户态库函数(动态链接的函数调用),通常也基于 ptrace。

  • ftrace:内核内建的跟踪框架,跟踪内核函数、上下文切换、IRQ、调度等,需在内核/tracefs 中使用(通常需 root)。

# -c 打印执行uptime时系统系统调用的时间、次数、出错次数和syscall strace -c uptime # -f 跟踪主进程及其所有子进程(对 shell 脚本、多进程程序很重要) strace -f ./my_script.sh # 显示 ls 命令执行过程中所有的系统调用(如 openat, read, write, close 等) strace ls /tmp # 把 strace 输出写入 debug.log,避免干扰终端 strace -o debug.log nginx -t # 跟踪 PID 为 1234 的进程(需有权限),常用于诊断卡住的服务 strace -p 1234 # 只跟踪特定类型的系统调用,如open、read、write、network等 strace -e trace=open,read,write curl https://example.com

strace 使用实践:定位一次系统无法解析域名故障。

无法访问外网域名,提示Name or service not know。且已检查系统DNS配置文件/etc/resolv.conf正确,排除DNS解析失败。域名解析通常跟系统读取文件相关,因此只查看open file的过程。

strace -e strace=open ping www.baidu.com

如上图所示在系统调用过程中出现/usr/lib64/libnss_dns.so.2文件缺失,则问题根因已确定为libnss_dns.so.2系统库文件缺失。libnss_dns.so.2文件由glibc-devel包产生,因此重新安装该包即可。

3.Valgrind - 内存泄漏检测 (该释放的资源没有及时释放)

内存泄漏原因:

1.new/delete,new[]/delete[] 没有配对使用,忘记释放动态分配的内存;

2.异常安全漏洞:异常改变了正常的执行流程,导致释放代码被跳过;

3.当多个部分共享同一内存时,释放责任不明确;

4.使用STL容器时存储了指针,清空容器时,指针指向的资源其实并没有释放,造成内存泄漏;

5.智能指针循环引用问题

方法:使用完内存或资源后立即释放;使用智能指针自动管理内存生命周期;RAII 类封装资源。

内存池能显著降低内存泄露的风险,一次性从系统申请一大块内存;后续的小对象分配不再调用 new/malloc,而是从池中切分;当整个池不再需要时,一次性释放整块内存,无需逐个 delete。

valgrind

  • 安装完valgrind,编译程序时一定加上-g! gcc -g -o leak leak.c

  • 运行Valgrind检测,valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./leak

--tool=memcheck:使用内存检查工具(默认工具)

--leak-check=full:详细显示内存泄漏信息

--show-leak-kinds=all:显示所有类型的泄漏

--track-origins=yes 追踪未初始化值的来源

--log-file=valgrind.log 将输出保存到文件

--num-callers=20 显示20层调用栈

  • 分析Valgrind输出结果,解读关键信息,比如:

definitely lost: 100 bytes:明确的内存泄漏,100字节

by 0x10916D: main (leak.c:6):泄漏发生在 leak.c 文件的第6行(就是 malloc(100) 那行)

1 allocs, 0 frees:分配了1次,释放了0次

ASan

另一个方法是ASan(AddressSanitizer)生成报告,但不一定100%罗列出来问题。

优点是比 Valgrind 快很多,但泄漏检测不如 Valgrind 精确。需额外开启内存泄漏检测:

gcc -fsanitize=address -fno-omit-frame-pointer -g -o leak leak.c

http://www.jsqmd.com/news/1125353/

相关文章:

  • JBoss 6.1.0.Final 弱口令加固实战:3步修改 jmx-console-users.properties 默认密码
  • 基于51/STM32单片机智能电饭煲 电饭锅设计 温度加热预约13(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Java 转大模型开发:后端程序员的升级路线,把工具链跑成稳定流程
  • Agent 云原生运行时:智能体也需要健康检查
  • CenterNet实战:从零搭建到模型测试的完整环境配置指南
  • GPT 输出不符合预期?从结构化提问到多轮优化的实用方法
  • CSS Cascade Layer:样式优先级要靠架构,不靠赌命名
  • Java毕设项目:中小型乡村民宿山庄综合业务管理系统的设计与实现 基于 Java 的民宿客户信息与消费记录管理系统 (源码+文档,讲解、调试运行,定制等)
  • AT 指令学习手册:从对话逻辑到实战排错
  • Avalonia NativeControlHost
  • 做过亲子游定制之后,才知道本地靠谱旅行社不能忽略
  • 基于51/STM32单片机温湿度检测控制系统 DHT11环境监测大棚报警器12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 原神120帧解锁终极指南:免费提升游戏流畅度的完整教程
  • 104. GaN功率模块集成驱动与高频磁性元件设计
  • 不同规模企业如何选择RFID资产管理系统?一份务实的选型指南
  • 【大白话说Java面试题 第153题】【06_Spring篇】第13题:Spring 中 Bean 是线程安全的吗?
  • 预训练让时序模型零样本胜出
  • 大学生AI学习工具选择指南:ChatGPT、DeepSeek与Gemini实战适配
  • 外卖做了400单,到手不到1000块:一笔账背后的行业困局
  • Java毕业设计-基于 SpringBoot 的 Cosplay 交流论坛的设计与实现 前后端分离的二次元 Cosplay 分享社区平台(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • 基于STM32单片机车位引导 智能停车场计费系统 刷卡识别 WIFI成品12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • Skills 编写规范与经验指南
  • 服务器安全(Windows Server+Linux)
  • 电容式触摸按键 PCB 设计 10 要点:从 PAD 形状到走线间距的实战避坑
  • 终极指南:5分钟快速导出QQ空间全部历史说说的完整解决方案
  • Linux groupdel命令详解|用户组删除、主组报错解决、强制删除实战教程
  • PyTorch 2.12 LSTM 时间序列预测实战:NASA IGBT 退化数据 MSE 降至 0.004
  • MyBatisGX 0.2.0 发布:正式引入 MGXQL 对象查询语言
  • 蓝速科技视觉 3D 全息舱 AI 数字人一体机带灯与无灯款深度评测
  • 102. GaN功率器件动态导通电阻(RDS(on))退化机理