GDB/LLDB 本身不检测内存泄漏,需配合 AddressSanitizer 等工具;ASan 必须编译时加 -fsanitize=address -g,VSCode 中设 externalConsole: true 才能完整显示报错。

为什么用 GDB/LLDB 直接查内存泄漏效果很差
因为 gdb 和 lldb 本身不检测内存泄漏,它们只是运行时调试器——能停在崩溃点、看指针值、查调用栈,但不会告诉你哪块 malloc 没 free,也不会标记野指针。真正起作用的是配套工具:valgrind(Linux)、AddressSanitizer(跨平台)、或 macOS 的 malloc_debug。VSCode 调试配置里填对 miDebuggerPath 只是第一步,关键得让程序跑在带检测的运行时环境里。
- 直接用
gdb --args ./a.out启动,漏检率接近 100%:没插桩,没堆操作拦截 -
AddressSanitizer必须在编译时加-fsanitize=address -g,否则运行时无任何额外检查 - VSCode 的
launch.json中设"externalConsole": true才能看到ASan的报错输出(默认集成终端会截断或刷屏)
VSCode 中启用 AddressSanitizer 并配合 lldb/gdb 断点调试
不是“用 lldb 查泄漏”,而是“让程序在 ASan 环境下崩溃,再用 lldb 进去查现场”。这需要两层配合:编译参数 + launch 配置。
- 编译命令示例(Clang):
clang++ -g -fsanitize=address -O0 main.cpp -o main(-O0避免内联干扰栈回溯) -
launch.json关键项:{ "name": "(lldb) ASan build", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/main", "args": [], "stopAtEntry": false, "externalConsole": true, "MIMode": "lldb", "miDebuggerPath": "/usr/bin/lldb" } - 运行后若触发 ASan 报错(如
heap-use-after-free),终端会打印完整错误+栈,此时可在 VSCode 中手动附加:lldb ./main→process attach --pid XXX,或直接在报错前加断点(比如在疑似越界读写的函数入口)
用 gdb/lldb 查指针问题时必须开的选项
默认情况下,gdb 显示 std::vector 是缩略的,print ptr 可能只显示地址不展开内容,这对排查空指针或悬垂指针毫无帮助。
- 在
~/.gdbinit或 VSCode 的setupCommands里加:set print pretty on set print object on set print vtbl on set print static-members on
- 调试时别只信
print ptr,要结合:info registers(看寄存器是否为 0x0)、x/10gx $rdi(查看指针指向的原始内存)、bt full(确认对象生命周期是否已结束) - 对智能指针,
print *ptr.get()比print ptr更可靠;std::shared_ptr还可查ptr.use_count()
macOS 下 lldb 需绕过的两个坑
Apple Silicon(M1/M2)和较新 macOS 版本对调试器权限和符号加载更严格,常见症状是断点不命中、变量显示 <optimized out>、或 frame variable 返回空。
立即学习“C++免费学习笔记(深入)”;
- 确保二进制有完整调试信息:
clang++ -g -glldb main.cpp(不是-g就够,-glldb生成 lldb 友好格式) - 关闭 SIP 对调试器的限制:重启进恢复模式 → 终端运行
csrutil enable --without debug(仅开发机建议,勿在生产环境操作) - VSCode 中若提示
Unable to start debugging. Unable to find the debugger,检查miDebuggerPath是否指向/usr/bin/lldb(不是xcode-select -p下的路径)
mmap 内存未被跟踪。这时候得切回纯 gdb + watch *(int*)0x12345678 手动盯地址,而不是依赖自动化工具。


















