最简启动命令为valgrind --tool=callgrind ./your_program;需带./路径,不可后台运行,输出默认为callgrind.out.pid文件,无终端打印,须用callgrind_annotate解析。

Callgrind 启动命令最简写法
第一次跑 Callgrind,直接用 valgrind --tool=callgrind ./your_program 就能启动。它默认不输出详细调用图,只生成 callgrind.out.PID 文件,这是正常行为——别误以为“没跑起来”。
常见错误是加了 --dump-instr=yes 却没配 --collect-jumps=yes,结果跳转信息全丢;或者漏掉 ./ 导致找不到可执行文件(Valgrind 不查 PATH)。
-
./your_program必须带路径,哪怕当前目录也要写./ - 避免在命令末尾加
&后台运行——Callgrind 会因 stdout/stderr 重定向异常而静默失败 - 如果程序需要参数,放在命令最后:
valgrind --tool=callgrind ./a.out --input=file.txt
怎么让第一次运行就有函数调用次数和耗时
默认的 callgrind.out.PID 文件里只有指令计数,没有函数级统计。要看到 fn=<function_name></function_name> 行和 calls= 字段,必须显式启用函数调用收集:
用这个命令:valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes --collect-systime=yes --callgrind-out-file=callgrind.out ./your_program
其中关键点:
-
--dump-instr=yes:开启每条指令的计数(否则只有函数入口计数) -
--collect-jumps=yes:记录跳转,影响调用关系还原精度 -
--callgrind-out-file=callgrind.out:固定输出名,省得每次猜 PID -
--collect-systime=yes:加上系统时间开销,方便识别 I/O 瓶颈
运行完看不到结果?先检查这三件事
Callgrind 不打印任何分析结果到终端,纯靠输出文件。很多人卡在这一步,以为“没生成”:
- 确认当前目录下是否存在
callgrind.out(或类似callgrind.out.12345的文件),用ls -l callgrind*查 - 如果程序秒退但没生成文件,大概率是被信号终止(如 SIGSEGV)——加
--log-file=valgrind.log看报错 - 文件存在但
callgrind_annotate callgrind.out报 “no events found”,说明运行时没采到有效数据,通常是程序太快退出或用了fork()后子进程没被跟踪(需加--trace-children=yes)
Callgrind 和普通 Valgrind 内存检测不能混用
Callgrind 是性能分析工具,不是内存检测器。第一次运行时别手滑写成 valgrind --tool=callgrind --leak-check=full ./a.out——--leak-check 对 Callgrind 无效,还可能干扰计数逻辑,导致输出文件损坏或体积异常膨胀。
真要同时看内存和性能,得分开跑两次:
- 内存问题:
valgrind --leak-check=full ./a.out - 性能热点:
valgrind --tool=callgrind --dump-instr=yes ./a.out
Callgrind 输出文件本身不含内存错误信息,也解析不出堆栈泄漏位置——这点容易被忽略,尤其当程序既慢又疑似有 leak 时,别指望一个命令解决两类问题。











