valgrind

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Valgrind

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
-g -O1
for best results.
-O0
is also fine; avoid
-O2
+ which can produce false positives.
bash
valgrind --tool=memcheck \
         --leak-check=full \
         --show-leak-kinds=all \
         --track-origins=yes \
         --error-exitcode=1 \
         ./prog [args]
Key flags:
FlagDefaultEffect
--leak-check=full
summaryFull leak details
--show-leak-kinds=all
definiteShow all leak kinds
--track-origins=yes
noShow where uninit values came from (slow)
--error-exitcode=N
0Exit N if errors found (CI integration)
--log-file=file
stderrSave report to file
--suppressions=file
noneSuppress known FPs
--gen-suppressions=yes
noPrint suppression directives for errors
--max-stackframe=N
2000000Increase for deep stacks
--malloc-fill=0xAB
offFill allocated memory (detect uninit use)
--free-fill=0xCD
offFill freed memory (detect use-after-free)
编译时使用
-g -O1
以获得最佳效果。
-O0
也可以;避免使用
-O2
及以上优化等级,否则会产生误报。
bash
valgrind --tool=memcheck \
         --leak-check=full \
         --show-leak-kinds=all \
         --track-origins=yes \
         --error-exitcode=1 \
         ./prog [args]
关键参数:
参数默认值作用
--leak-check=full
摘要显示完整泄漏详情
--show-leak-kinds=all
明确泄漏显示所有泄漏类型
--track-origins=yes
显示未初始化值的来源(速度较慢)
--error-exitcode=N
0若发现错误则以状态码N退出(用于CI集成)
--log-file=file
标准错误输出将报告保存到文件
--suppressions=file
抑制已知误报
--gen-suppressions=yes
打印错误对应的抑制规则
--max-stackframe=N
2000000增大栈帧大小以支持深层栈
--malloc-fill=0xAB
关闭填充已分配内存(检测未初始化使用)
--free-fill=0xCD
关闭填充已释放内存(检测释放后使用)

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. 泄漏类型

KindMeaning
Definitely lostNo pointer to block
Indirectly lostLost via another lost block
Possibly lostPointer into middle of block
Still reachablePointer exists at exit; not a leak but never freed
For library code:
--show-leak-kinds=definite,indirect
reduces noise from still-reachable.
类型含义
Definitely lost无指针指向内存块
Indirectly lost通过另一个泄漏块导致的丢失
Possibly lost指针指向内存块中间
Still reachable程序退出时仍有指针指向;不属于泄漏但未被释放
对于库代码:使用
--show-leak-kinds=definite,indirect
可减少来自still-reachable的干扰信息。

4. Suppressions

4. 抑制规则

bash
undefined
bash
undefined

Generate 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
undefined
valgrind --suppressions=valgrind.supp ./prog
undefined

5. Cachegrind — cache simulation

5. Cachegrind — 缓存模拟

bash
valgrind --tool=cachegrind ./prog
bash
valgrind --tool=cachegrind ./prog

Output: 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 rate
cg_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 ./prog
bash
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./prog

Analyse

分析结果

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 ./prog
bash
valgrind --tool=massif ./prog

Visualise

可视化结果

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
    --error-exitcode=1
    to fail fast in CI
  • Use ASan (
    -fsanitize=address
    ) for faster memory checking during development
  • 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
    skills/runtimes/sanitizers
    for faster ASan/UBSan alternatives
  • Use
    skills/profilers/linux-perf
    for CPU-level profiling (faster than Cachegrind)
  • Use
    skills/profilers/flamegraphs
    to visualise Callgrind output
  • 使用
    skills/runtimes/sanitizers
    获取更快的ASan/UBSan替代方案
  • 使用
    skills/profilers/linux-perf
    进行CPU级分析(比Cachegrind更快)
  • 使用
    skills/profilers/flamegraphs
    可视化Callgrind输出结果