GDB 调试与 Core Dump(段错误)排查指南(Linux/C/C++)

GDB 调试与 Core Dump(段错误)排查指南(Linux/C/C++)

GDB 调试与 Core Dump(段错误)排查指南(Linux/C/C++)

目录(大纲)

1. GDB 是什么?能解决什么问题?

GDB(GNU Debugger)是 Linux 平台最常用的程序调试器之一,主要用来:

  • 断点调试:在指定代码行/函数处暂停,观察程序状态。
  • 单步执行:一行一行执行,定位逻辑错误。
  • 查看/修改变量:实时查看局部变量、参数、全局变量,必要时可临时修改变量值验证思路。
  • 调用栈回溯:程序崩溃后查看调用链(bt/where),快速定位问题入口。
  • Core Dump 事后分析:程序崩溃生成 core 文件后,用 GDB 还原“事故现场”。
适用场景:段错误(SIGSEGV)、非法访问、野指针、栈溢出、数组越界、use-after-free 等。

2. 编译准备:一定要带调试信息

调试/分析崩溃时,可执行文件与崩溃现场必须匹配(同版本、同编译产物)。建议:

# 推荐:关闭过度优化,保留调试信息 gcc -g -O0 main.c -o app # 或者 C++ g++ -g -O0 main.cpp -o app 
  • -g:生成调试符号(行号、变量名、函数名)
  • -O0 / -Og:降低优化程度,避免变量被优化掉导致 <value optimized out>

3. GDB 常用命令速查(高频)

3.1 启动与加载

# 方式1:直接调试可执行文件 gdb ./app # 方式2:带参数启动(也可在 gdb 内 set args) gdb --args ./app arg1 arg2 # 方式3:调试 core 文件(事后分析) gdb ./app /path/to/core # 或 gdb -c /path/to/core ./app 

3.2 断点/运行控制

命令缩写作用
break <位置>b设置断点(行号/函数名/文件:行号)
info breakpointsi b查看断点列表
delete <编号>d删除断点
runr启动程序(命中断点会停住)
continuec继续运行到下一个断点/结束
nextn单步执行(不进入函数)
steps单步执行(进入函数)
finish跑完当前函数并返回到上一层
untilu运行到指定行/跳出循环场景常用
quitq退出 gdb

常见断点位置写法:

(gdb) b main (gdb) b 20 (gdb) b main.c:20 (gdb) b foo if x > 10 

3.3 查看代码/栈/变量

命令缩写作用
listl显示源代码(可 l 1 从第1行)
where / backtracebt查看调用栈
bt full调用栈 + 每帧局部变量(core 分析很有用)
frame <n>f切换到第 n 层栈帧
up / down在栈帧之间上下移动
print <表达式>p打印变量/表达式值
display <表达式>每次停住自动打印
info locals打印当前栈帧所有局部变量
info args打印当前函数参数
info registers查看寄存器

3.4 内存查看(定位越界/野指针很关键)

x(examine)用于按格式查看内存:

# x/<数量><格式><单位> <地址> (gdb) x/16xb ptr # 16字节,按16进制byte显示 (gdb) x/8xw ptr # 8个word(4字节),按16进制显示 (gdb) x/s ptr # 按字符串显示 (gdb) x/i $pc # 反汇编当前指令 

4. 实战:用 GDB 定位段错误(SIGSEGV)

4.1 构造一个会崩溃的例子

main.c

#include<stdio.h>#include<stdlib.h>intmain(){int*p =NULL;*p =123;// 对 NULL 解引用,触发段错误return0;}

编译运行:

gcc -g -O0 main.c -o app ./app 

4.2 用 GDB 运行并定位

gdb ./app 

在 gdb 中:

(gdb) run Program received signal SIGSEGV, Segmentation fault. (gdb) bt #0 main () at main.c:7 (gdb) list (gdb) info locals (gdb) p p $1 = (int *) 0x0 

这类问题的定位套路:

  • bt 看栈:崩溃点在哪个函数、哪一行。
  • frame/list 看上下文:看崩溃行附近逻辑。
  • 最后 p/info locals/info args:确认关键指针、数组下标、长度参数是否异常。

5. Core Dump:程序崩了也能“回放现场”

当程序崩溃时,系统可把当时的内存映射、寄存器、栈等信息写入 core 文件,用于事后分析。

5.1 开启 core 文件生成(Linux)

# 查看当前限制(0 表示不生成)ulimit -c # 临时开启(当前 shell 生效)ulimit -c unlimited 

core 文件路径与命名常由内核参数控制:

cat /proc/sys/kernel/core_pattern 
注意:线上环境经常被 systemd 接管 core,core 可能不落在当前目录。需要结合发行版策略确认落盘位置。

5.2 使用 GDB 分析 core

假设生成了 core 文件:

gdb ./app core 

高频排查命令:

(gdb) bt (gdb) bt full (gdb) info threads (gdb) thread apply all bt (gdb) frame 0 (gdb) info locals (gdb) info args (gdb) p some_ptr (gdb) x/32xb some_ptr 

如果看到类似提示:

  • no debugging symbols found:二进制没有 -g 调试符号
  • warning: core file may not match specified executable file:core 与可执行文件版本不匹配

6. 段错误(Segmentation fault)常见原因总结

段错误本质:访问了不允许访问的内存区域(地址不存在或受保护)。典型原因:

  • 空指针/野指针解引用char *p = NULL; *p = 'x';
  • 已释放内存再次使用(use-after-free)
  • 数组越界/指针越界:写穿栈/堆,导致随机崩溃
  • 返回局部变量地址:函数返回后栈帧销毁,地址失效
  • 栈溢出:递归太深、局部数组过大
  • 字符串处理长度错误:如 sprintf 等导致溢出(建议 snprintf

7. 高效排查套路(建议你照着做)

7.1 现场调试(可复现崩溃)

  • 先断点b mainb 可疑函数
  • 单步逼近n/s
  • 观察关键数据pinfo localsinfo args

7.2 事后分析(只有 core)

  • gdb ./app core
  • bt full 一步到位获取:崩溃行 + 参数 + 局部变量
  • x/ 查看指针指向内存是否合理
  • 多线程程序:info threads + thread apply all bt

7.3 变量被优化掉怎么办?

如果出现:<value optimized out>

  • 编译时用 -O0-Og
  • 确保带 -g

8. 进阶小技巧(可选但很实用)

# 让长数组/长字符串完整打印(默认可能截断) (gdb) set print elements 0 # 打印结构体更友好 (gdb) set print pretty on # 查看动态库与映射 (gdb) info sharedlibrary (gdb) info proc mappings 

9. 总结

  • GDB = 运行时调试 + 崩溃现场还原 的核心工具。
  • -g、尽量 -O0/-Og,能显著提升定位效率。
  • 段错误优先用:btlistinfo locals/argsp/x 的套路。
  • Core Dump 是线上排查的关键:可执行文件必须与 core 匹配

参考资料(可扩展阅读)

  • https://stackoverflow.com/questions/5115613/core-dump-file-analysis
  • https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st
  • https://cgi.cse.unsw.edu.au/~learn/debugging/modules/gdb_coredumps/

Read more

安装 启动 使用 Neo4j的超详细教程

安装 启动 使用 Neo4j的超详细教程

最近在做一个基于知识图谱的智能生成项目。需要用到Neo4j图数据库。写这篇文章记录一下Neo4j的安装及其使用。 一.Neo4j的安装 1.首先安装JDK,配环境变量。(参照网上教程,很多) Neo4j是基于Java的图形数据库,运行Neo4j需要启动JVM进程,因此必须安装JAVA SE的JDK。从Oracle官方网站下载 Java SE JDK。我使用的版本是JDK1.8 2.官网上安装neo4j。 官方网址:https://neo4j.com/deployment-center/  在官网上下载对应版本。Neo4j应用程序有如下主要的目录结构: bin目录:用于存储Neo4j的可执行程序; conf目录:用于控制Neo4j启动的配置文件; data目录:用于存储核心数据库文件; plugins目录:用于存储Neo4j的插件; 3.配置环境变量 创建主目录环境变量NEO4J_HOME,并把主目录设置为变量值。复制具体的neo4j文件地址作为变量值。 配置文档存储在conf目录下,Neo4j通过配置文件neo4j.conf控制服务器的工作。默认情况下,不需

企业微信群机器人Webhook配置全攻略:从创建到发送消息的完整流程

企业微信群机器人Webhook配置全攻略:从创建到发送消息的完整流程 在数字化办公日益普及的今天,企业微信作为国内领先的企业级通讯工具,其群机器人功能为团队协作带来了极大的便利。本文将手把手教你如何从零开始配置企业微信群机器人Webhook,实现自动化消息推送,提升团队沟通效率。 1. 准备工作与环境配置 在开始创建机器人之前,需要确保满足以下基本条件: * 企业微信账号:拥有有效的企业微信管理员或成员账号 * 群聊条件:至少包含3名成员的群聊(这是创建机器人的最低人数要求) * 网络环境:能够正常访问企业微信服务器 提示:如果是企业管理员,建议先在"企业微信管理后台"确认机器人功能是否已对企业开放。某些企业可能出于安全考虑会限制此功能。 2. 创建群机器人 2.1 添加机器人到群聊 1. 打开企业微信客户端,进入目标群聊 2. 点击右上角的群菜单按钮(通常显示为"..."或"⋮") 3. 选择"添加群机器人"选项 4.

Flowise物联网融合:与智能家居设备联动的应用设想

Flowise物联网融合:与智能家居设备联动的应用设想 1. Flowise:让AI工作流变得像搭积木一样简单 Flowise 是一个真正把“AI平民化”落地的工具。它不像传统开发那样需要写几十行 LangChain 代码、配置向量库、调试提示词模板,而是把所有这些能力打包成一个个可拖拽的节点——就像小时候玩乐高,你不需要懂塑料怎么合成,只要知道哪块该拼在哪,就能搭出一座城堡。 它诞生于2023年,短短一年就收获了45.6k GitHub Stars,MIT协议开源,意味着你可以放心把它用在公司内部系统里,甚至嵌入到客户交付的产品中,完全不用担心授权问题。最打动人的不是它的技术多炫酷,而是它真的“不挑人”:产品经理能搭出知识库问答机器人,运营同学能配出自动抓取竞品文案的Agent,连刚学Python两周的实习生,也能在5分钟内跑通一个本地大模型的RAG流程。 它的核心逻辑很朴素:把LangChain里那些抽象概念——比如LLM调用、文档切分、向量检索、工具调用——变成画布上看得见、摸得着的方块。你拖一个“Ollama LLM”节点,再拖一个“Chroma Vector

OpenClaw配置Bot接入飞书机器人+Kimi2.5

OpenClaw配置Bot接入飞书机器人+Kimi2.5

上一篇文章写了Ubuntu_24.04下安装OpenClaw的过程,这篇文档记录一下接入飞书机器+Kimi2.5。 准备工作 飞书 创建飞书机器人 访问飞书开放平台:https://open.feishu.cn/app,点击创建应用: 填写应用名称和描述后就直接创建: 复制App ID 和 App Secret 创建成功后,在“凭证与基础信息”中找到 App ID 和 App Secret,把这2个信息复制记录下来,后面需要配置到openclaw中 配置权限 点击【权限管理】→【开通权限】 或使用【批量导入/导出权限】,选择导入,输入以下内容,如下图 点击【下一步,确认新增权限】即可开通所需要的权限。 配置事件与回调 说明:这一步的配置需要先讲AppId和AppSecret配置到openclaw成功之后再设置订阅方式,