本文由 AI 自动摘录整理,原始链接:一个数组越界,竟让我排查了几天
推荐指数:8/10(推荐读原文)
背景
程序跑了几天好好的,换个位置就段错误死机。屏蔽两行三角函数代码就正常,打开就必崩——但问题根源和那两行代码毫无关系。最终真凶是一个"隔山打牛"式的数组越界。
核心观点
打印法可能把你带偏:屏蔽代码后"不崩了",只是切断了越界的触发路径,并没有解决根本问题。表象往往和根因相隔甚远。
远程 GDB 精确定位崩溃点:gdbserver + VSCode 远程调试,段错误发生时能精确知道崩溃的代码行号,比打印法更可靠。
数组越界"隔山打牛":一个 5 元素的 float 数组
arr,实际写到了arr[5]、arr[6]、arr[7]、arr[8]。而arr[8]的地址正好是静态全局变量fd的地址,写入操作直接篡改了fd的值,导致段错误。
关键技巧
-fdata-sections 编译参数:让每个变量放到独立的 section 中,链接器生成 map 文件时就会包含 static 变量的地址信息,方便分析内存布局。
AddressSanitizer(-fsanitize=address):对付内存类 bug 的"大杀器",会直接报出数组越界的精确位置和调用栈,可能 10 分钟就能定位根因。
调试工具速查表
| 工具/方法 | 适用场景 | 优势 |
|---|---|---|
| log 打印法 | 快速初筛 | 简单直接,零成本 |
| 远程 GDB | 精确定位崩溃行 | 可看调用栈和变量值 |
| core dump + gdb | 事后分析 | 不需要复现,离线分析 |
| strace | 系统调用级跟踪 | 排查文件/网络/权限问题 |
| AddressSanitizer | 内存越界/溢出/UAF | 编译期插桩,精确到行 |
| map 文件 + -fdata-sections | 分析变量内存布局 | 查看 static 变量地址 |
经验总结
表象 ≠ 根因:通过屏蔽/打开某些代码来定位问题时,看到的可能只是 bug 的表象。要多思考"为什么",从根本上解决。
选对工具事半功倍:打印法虽然常用,但遇到内存踩踏类 bug 时容易把人带偏。远程 GDB 和 map 文件是更高效的手段。
AI 辅助排查:有明显代码缺陷的代码,AI review 分分钟就能检测出来。结对分析可以让 AI 检查可疑代码是否存在缺陷。
摘录时间:2026-03-14