valgrind
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseValgrind
Valgrind
Purpose
用途
Guide agents through Valgrind tools: Memcheck for memory errors, Cachegrind for cache simulation, Callgrind for call graphs, and Massif for heap profiling.
指导使用者了解Valgrind工具:Memcheck用于内存错误检测,Cachegrind用于缓存模拟,Callgrind用于调用图分析,Massif用于堆内存分析。
Triggers
触发场景
- "My program has a memory leak / use-after-free"
- "I can't use ASan — can I use Valgrind instead?"
- "How do I profile cache behaviour without perf?"
- "How do I visualize call graphs with Callgrind?"
- "How do I profile heap allocation patterns?"
- "Valgrind reports errors in third-party code I can't fix"
- "我的程序存在内存泄漏/释放后使用问题"
- "我无法使用ASan — 可以用Valgrind替代吗?"
- "如何不使用perf来分析缓存行为?"
- "如何用Callgrind可视化调用图?"
- "如何分析堆内存分配模式?"
- "Valgrind报告了我无法修复的第三方代码错误"
Workflow
使用流程
1. Memcheck — memory error detection
1. Memcheck — 内存错误检测
Compile with for best results. is also fine; avoid + which can produce false positives.
-g -O1-O0-O2bash
valgrind --tool=memcheck \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--error-exitcode=1 \
./prog [args]Key flags:
| Flag | Default | Effect |
|---|---|---|
| summary | Full leak details |
| definite | Show all leak kinds |
| no | Show where uninit values came from (slow) |
| 0 | Exit N if errors found (CI integration) |
| stderr | Save report to file |
| none | Suppress known FPs |
| no | Print suppression directives for errors |
| 2000000 | Increase for deep stacks |
| off | Fill allocated memory (detect uninit use) |
| off | Fill freed memory (detect use-after-free) |
编译时使用以获得最佳效果。也可以;避免使用及以上优化等级,否则会产生误报。
-g -O1-O0-O2bash
valgrind --tool=memcheck \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--error-exitcode=1 \
./prog [args]关键参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
| 摘要 | 显示完整泄漏详情 |
| 明确泄漏 | 显示所有泄漏类型 |
| 否 | 显示未初始化值的来源(速度较慢) |
| 0 | 若发现错误则以状态码N退出(用于CI集成) |
| 标准错误输出 | 将报告保存到文件 |
| 无 | 抑制已知误报 |
| 否 | 打印错误对应的抑制规则 |
| 2000000 | 增大栈帧大小以支持深层栈 |
| 关闭 | 填充已分配内存(检测未初始化使用) |
| 关闭 | 填充已释放内存(检测释放后使用) |
2. Understanding Memcheck output
2. 理解Memcheck输出
text
==12345== Invalid read of size 4
==12345== at 0x4007A2: foo (main.c:15)
==12345== by 0x400846: main (main.c:30)
==12345== Address 0x5204040 is 0 bytes after a block of size 40 alloc'd
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==12345== by 0x40074B: main (main.c:25)- Invalid read/write: out-of-bounds access; check array bounds
- Use of uninitialised value: read before write; use
--track-origins=yes - Invalid free / double free: mismatched malloc/free; check ownership
- Definitely lost: reachable via no pointers; clear leak
- Indirectly lost: lost through a chain; usually means one root leak
- Possibly lost: might be pointing into the middle of a block; often FP with custom allocators
text
==12345== Invalid read of size 4
==12345== at 0x4007A2: foo (main.c:15)
==12345== by 0x400846: main (main.c:30)
==12345== Address 0x5204040 is 0 bytes after a block of size 40 alloc'd
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==12345== by 0x40074B: main (main.c:25)- 无效读/写:越界访问;检查数组边界
- 使用未初始化值:读取未写入的内容;使用参数
--track-origins=yes - 无效释放/重复释放:malloc/free不匹配;检查内存所有权
- 明确泄漏:无指针指向该内存块;明确的泄漏
- 间接泄漏:通过另一个泄漏块导致的泄漏;通常意味着存在一个根泄漏点
- 可能泄漏:指针指向内存块的中间位置;自定义分配器下常出现误报
3. Leak kinds
3. 泄漏类型
| Kind | Meaning |
|---|---|
| Definitely lost | No pointer to block |
| Indirectly lost | Lost via another lost block |
| Possibly lost | Pointer into middle of block |
| Still reachable | Pointer exists at exit; not a leak but never freed |
For library code: reduces noise from still-reachable.
--show-leak-kinds=definite,indirect| 类型 | 含义 |
|---|---|
| Definitely lost | 无指针指向内存块 |
| Indirectly lost | 通过另一个泄漏块导致的丢失 |
| Possibly lost | 指针指向内存块中间 |
| Still reachable | 程序退出时仍有指针指向;不属于泄漏但未被释放 |
对于库代码:使用可减少来自still-reachable的干扰信息。
--show-leak-kinds=definite,indirect4. Suppressions
4. 抑制规则
bash
undefinedbash
undefinedGenerate suppression for current error
为当前错误生成抑制规则
valgrind --gen-suppressions=yes ./prog 2>&1 | grep -A20 '{'
valgrind --gen-suppressions=yes ./prog 2>&1 | grep -A20 '{'
Example suppression file (valgrind.supp)
示例抑制文件(valgrind.supp)
{
openssl_uninit
Memcheck:Cond
fun:SHA256_Init
...
}
{
openssl_uninit
Memcheck:Cond
fun:SHA256_Init
...
}
Use suppression file
使用抑制文件
valgrind --suppressions=valgrind.supp ./prog
undefinedvalgrind --suppressions=valgrind.supp ./prog
undefined5. Cachegrind — cache simulation
5. Cachegrind — 缓存模拟
bash
valgrind --tool=cachegrind ./progbash
valgrind --tool=cachegrind ./progOutput: cachegrind.out.PID
输出文件:cachegrind.out.PID
Annotate source
为源代码添加注释
cg_annotate cachegrind.out.12345 --auto=yes
cg_annotate cachegrind.out.12345 --auto=yes
Diff two runs
对比两次运行结果
cg_diff cachegrind.out.before cachegrind.out.after
Key metrics:
- `I1mr` / `ILmr`: L1/LL instruction cache miss rate
- `D1mr` / `DLmr`: L1/LL data read miss rate
- `D1mw` / `DLmw`: L1/LL data write miss ratecg_diff cachegrind.out.before cachegrind.out.after
关键指标:
- `I1mr` / `ILmr`:L1/LL指令缓存缺失率
- `D1mr` / `DLmr`:L1/LL数据读取缺失率
- `D1mw` / `DLmw`:L1/LL数据写入缺失率6. Callgrind — call graph profiling
6. Callgrind — 调用图分析
bash
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./progbash
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./progAnalyse
分析结果
callgrind_annotate callgrind.out
callgrind_annotate callgrind.out
Visualise in KCachegrind (GUI)
在KCachegrind(GUI工具)中可视化
kcachegrind callgrind.out
Callgrind is slower than `perf` but works without root and provides exact call counts.kcachegrind callgrind.out
Callgrind比`perf`慢,但无需root权限,且能提供精确的调用计数。7. Massif — heap profiling
7. Massif — 堆内存分析
bash
valgrind --tool=massif ./progbash
valgrind --tool=massif ./progVisualise
可视化结果
ms_print massif.out.PID | less
ms_print massif.out.PID | less
GUI
GUI工具
massif-visualizer massif.out.PID
Massif shows heap usage over time; useful for finding peak allocation sites and tracking gradual leaks.massif-visualizer massif.out.PID
Massif展示堆内存随时间的使用情况;有助于发现峰值分配点和追踪渐进式泄漏。8. Performance considerations
8. 性能注意事项
Valgrind Memcheck runs ~10-50x slower than native. Mitigations:
- Use a shorter representative workload
- Use to fail fast in CI
--error-exitcode=1 - Use ASan () for faster memory checking during development
-fsanitize=address - Reserve Valgrind for cases where ASan can't be used (old toolchains, production-like environments)
For a comparison of Valgrind vs ASan, see references/valgrind-vs-asan.md.
Valgrind Memcheck的运行速度比原生程序慢约10-50倍。缓解方法:
- 使用更简短的代表性工作负载
- 在CI中使用快速终止
--error-exitcode=1 - 开发阶段使用ASan()进行更快的内存检查
-fsanitize=address - 在ASan无法使用的场景下(旧工具链、类生产环境)使用Valgrind
关于Valgrind与ASan的对比,可参考references/valgrind-vs-asan.md。
Related skills
相关技能
- Use for faster ASan/UBSan alternatives
skills/runtimes/sanitizers - Use for CPU-level profiling (faster than Cachegrind)
skills/profilers/linux-perf - Use to visualise Callgrind output
skills/profilers/flamegraphs
- 使用获取更快的ASan/UBSan替代方案
skills/runtimes/sanitizers - 使用进行CPU级分析(比Cachegrind更快)
skills/profilers/linux-perf - 使用可视化Callgrind输出结果
skills/profilers/flamegraphs