VSCode本身不内置内存泄漏检测能力,必须依赖外部工具(如AddressSanitizer)、正确编译参数(如-fsanitize=address或Windows CRT调试标志)及合理launch.json配置(含"externalConsole": true)三者协同才能生效;缺一不可。

VSCode 本身不内置内存泄漏检测能力,必须靠外部工具插桩 + 正确编译参数 + 合理 launch 配置三者配合才能生效;单独改 launch.json 或只装插件,基本查不到真实泄漏。
编译时必须加 -fsanitize=address(Linux/macOS)或启用 CRT 检测(Windows)
AddressSanitizer(ASan)是跨平台最实用的运行时检测方案,但它不会自动启用——必须在编译命令里显式加入:
-
clang++ -g -O0 -fsanitize=address main.cpp -o main(-O0防内联干扰栈回溯,-g保留调试符号) -
g++ -g -O0 -fsanitize=address main.cpp -o main(GCC 也支持,但部分旧版本需 8.0+) - Windows 下若用 MSVC,则换用 CRT 自带检测:
#define _CRTDBG_MAP_ALLOC+_CrtSetDbgFlag(...),且必须 Debug 模式编译,Release 下全失效 - 漏掉
-fsanitize=address或没开 Debug,launch.json里配得再全也只会静默运行,零报错、零提示
launch.json 中设 "externalConsole": true 才能看见 ASan 报错
ASan 的错误信息(如 heap-use-after-free、malloc not freed)默认会输出到控制台,而 VSCode 内置终端常截断、刷屏或吞掉 ANSI 转义序列,导致关键堆栈丢失。
- 必须在配置中显式写
"externalConsole": true,否则你只看到程序崩溃退出,看不到任何泄漏线索 - 对应配置示例(LLDB):
"name": "(lldb) ASan build"、"MIMode": "lldb"、"miDebuggerPath": "/usr/bin/lldb" - GDB 同理,但注意 macOS 上系统自带 GDB 已弃用,推荐用 LLDB 或自行编译 GDB
- 不要依赖
setupCommands里塞set environment来“启用检测”——那对 ASan 完全无效
别指望 GDB/LMDB 直接“查出泄漏”,它们只负责看崩溃现场
GDB 和 LLDB 是调试器,不是内存分析器。它们能做的事很明确:停在 ASan 触发的崩溃点、打印寄存器、查看栈帧、读内存内容。但“哪次 malloc 没 free”这种问题,它们自己答不了。
- 典型流程是:ASan 崩溃 → 终端打出完整错误 + 栈 → 你根据栈定位到可疑函数 → 在该函数入口打断点 → 用
info registers看指针是否为0x0,用x/10gx $rdi查原始内存,用bt full确认对象生命周期 - 对
std::shared_ptr,print *ptr.get()比print ptr更可靠;ptr.use_count()能帮你判断是否意外延长了生命期 - 如果程序没崩、只是内存缓慢上涨,ASan 不触发,就得换工具:Linux 用
valgrind --tool=memcheck,macOS 用malloc_history或开启MallocStackLogging
最容易被忽略的一点:ASan 报错后进程已终止,你无法在 VSCode 里“继续调试”。必须在崩溃前就设好断点,或者用 lldb ./main 启动后手动 process attach --pid XXX 进去抓现场——这步没准备,等于白配。


















