GDB和LLDB本身不检测内存泄漏,必须配合AddressSanitizer或Valgrind等工具;它们仅负责在ASan/Valgrind触发崩溃后分析现场,而非主动追踪malloc/free匹配。

GDB 和 LLDB 本身不查内存泄漏,硬配调试器也白搭——必须让程序跑在 AddressSanitizer(ASan)或 Valgrind 环境下,再用调试器看崩溃现场。
为什么直接用 gdb/lldb 查不到 malloc 没 free
gdb 和 lldb 是运行时调试器,不是内存检测器。它们能停在 segfault、打印 ptr 值、显示调用栈,但不会标记哪次 malloc 没配对 free,也不会拦截堆操作。你看到的“空指针崩溃”,大概率是 ASan 先报错后触发的二次崩溃。
- 没加编译插桩(如
-fsanitize=address),gdb 就只是个普通调试器,和泄漏完全无关 - ASan 的错误信息(如
heap-use-after-free、leak detected)只在程序退出时集中输出,必须确保终端能完整看到 - Valgrind(Linux)和
malloc_debug(macOS)同理:它们才是检测主体,gdb/lldb 只负责事后分析
VSCode 中启用 AddressSanitizer 的最小可行配置
关键不在 launch.json 里写多少字段,而在编译命令和终端输出是否闭环。漏掉任一环,ASan 就静默失效。
- 编译必须带
-fsanitize=address -g -O0:-O0防止内联干扰栈回溯,-g保证符号可读 -
launch.json必须设"externalConsole": true:集成终端会截断 ASan 的多行报错,尤其在 macOS/Linux 下容易刷屏丢信息 -
"program"字段必须指向刚用 ASan 编译出的二进制,不能是旧的、没加-fsanitize的版本 - 验证是否生效:运行
./a.out后故意触发越界(如访问arr[100]),应立刻看到类似ERROR: AddressSanitizer: heap-buffer-overflow on address 0x...的输出
ASan 报错后怎么用 lldb/gdb 进去查现场
这不是“边跑边查泄漏”,而是“等 ASan 崩溃后,用调试器 attach 到崩溃进程或复现现场”。ASan 会主动 abort,此时进程还在,栈帧完整。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 启动前在疑似问题函数入口加断点,比如
break my_alloc_func,再 run,比盲目等崩溃更可控 - 崩溃后若终端还活着(
externalConsole: true保证了这点),记下 PID,然后新开终端执行:lldb ./a.out→process attach --pid XXX - 进去了先
bt full看完整调用栈,再frame variable或print *ptr.get()(智能指针)确认对象状态 - 别信
print ptr的默认输出——它常只显示地址。要用x/10gx $rdi(x86_64)看原始内存,或info registers确认寄存器是否为0x0
常见踩坑点:路径、权限、扩展冲突
很多“配置好了却没反应”的问题,根源不在 JSON 写法,而在工具链没对齐或环境被覆盖。
-
miDebuggerPath写的是/usr/bin/gdb,但系统实际用的是 Homebrew 安装的gdb(需签名)或lldb;macOS 上更推荐直接配"type": "lldb"+codelldb扩展 - tasks.json 里用了
g++,但终端中g++ --version显示的是 clang++(macOS 默认),导致-fsanitize=address被忽略或静默失败 - 同时启用了 Microsoft 的 C/C++ 扩展(
cppdbg)和CodeLLDB,后者被前者劫持调试协议,表现为“调试按钮灰掉”或“no debug adapter” - Windows 下用 MinGW-w64,但
gdb.exe路径含中文或空格(如C:\Program Files\...),VSCode 无法调用
真正卡住人的从来不是 launch.json 多写一行,而是编译没走 ASan、终端吞了报错、或者两个调试扩展在后台打架。先跑通 clang++ -fsanitize=address -g -O0 main.cpp -o main && ./main 看到 ASan 输出,再往 VSCode 里搬,顺序错了,后面全白忙。

















