Linux下使用callgrind统计函数调用时程序运行结果异常
Valgrind搭配Callgrind统计函数调用时程序秒退、结果异常的排查方法
- 先核对命令格式是否正确。Callgrind的参数必须写在目标程序路径前面,程序自身的启动参数、输入输出重定向要全部放在目标程序路径之后。如果参数位置写错,valgrind会提前截断命令,根本不会启动目标程序的核心逻辑,自然会立刻输出结果。最基础的正确统计命令格式参考:
valgrind --tool=callgrind --callgrind-out-file=callgrind_stat.out ./your_target_program [程序正常运行所需的全部启动参数] - 排查程序是否存在环境检测逻辑。Callgrind运行时会模拟CPU执行环境,不会透传原生硬件的全部特性,部分带反调试、运行环境校验逻辑的程序,检测到自己运行在valgrind环境下时,会直接跳过耗时的核心计算分支走快速退出流程,运行速度自然会比原生执行快很多。你可以先运行不带任何工具参数的
valgrind ./your_target_program做验证,如果这个场景下程序也会立刻结束,就说明是程序自身的环境检测逻辑导致的,和Callgrind的统计功能无关。 - 检查Callgrind相关参数配置是否错误。如果你加了
--instr-atstart=no参数,Callgrind启动时默认不会做代码插桩,要是程序在你手动开启插桩前就走到了退出逻辑,就会生成空的统计文件、秒出结果。 - 确认目标程序的编译、打包方式是否兼容Valgrind。Valgrind对加壳(比如UPX压缩)、强混淆、特殊指令集编译、完全静态编译的程序支持度很差,这类程序加载时Callgrind无法完成正常插桩,会直接触发加载失败秒退,此时终端输出会出现无法识别指令、可执行文件格式错误之类的提示,和程序正常运行的输出有明显区别。
快速验证技巧:可以给程序入口加一行启动日志打印,或者用strace跟踪valgrind运行时的系统调用序列,如果看不到程序正常运行时会触发的读输入文件、启动计算线程之类的系统调用,就说明程序根本没有进入正常运行流程,不需要在统计参数上浪费时间排查。
内容的提问来源于stack exchange,提问作者dearn44
相关产品推荐
相关产品推荐

