调试技巧之 :valgrind –tool=callgrind & kcachegrind
gprof这个常用的性能工具,用来性能调优很方便。但是!!有个致命的缺点,不能处理动态链接库(dlopen()加载的)。sigh…
那遇到动态链接库怎么调优呢,用这个工具callgrind。
同样是valgrind工具集中的一个,使用也是同样方便。gcc带上-g参数,然后用callgrind运行!
同样取上一个程序:
#include <stdio.h> #include <stdlib.h> void f1() { int i; int *p; for (i = 0; i < 10; i++) { p = malloc(sizeof(int)); *p = 10; free(p); } } void f2() { int i; int *p; for (i = 0; i < 20; i++) { p = malloc(sizeof(int)); *p = 10; free(p); } } void f3() { int i; int *p; for (i = 0; i < 30; i++) { p = malloc(sizeof(int)); *p = 10; free(p); } } int main() { int i; for (i = 0; i < 1000000; i++) { f1(); f2(); f3(); } return 0; }
编译运行:
gcc -o test -g test.c valgrind --tool=callgrind ./test
要有耐心,上了callgrind运行的程序会非常的慢(理解万岁)。
运行完之后文件夹下出现了callgrind.out.***便是日志文件。更massif一样,需要用工具转化:
callgrind_annotate callgrind.out.438
结果如下:
-------------------------------------------------------------------------------- Profile data file 'callgrind.out.438' (creator: callgrind-3.5.0) -------------------------------------------------------------------------------- I1 cache: D1 cache: L2 cache: Timerange: Basic block 0 - 977300000 Trigger: Program termination Profiled target: ./test (PID 438, part 1) Events recorded: Ir Events shown: Ir Event sort order: Ir Thresholds: 99 Include dirs: User annotated: Auto-annotation: off -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 4,136,177,734 PROGRAM TOTALS -------------------------------------------------------------------------------- Ir file:function -------------------------------------------------------------------------------- 1,353,303,232 ???:_int_free [/lib64/libc-2.12.90.so] 1,162,995,238 ???:_int_malloc [/lib64/libc-2.12.90.so] 972,686,762 ???:malloc [/lib64/libc-2.12.90.so] 401,761,897 ???:free [/lib64/libc-2.12.90.so] 119,471,210 test.c:f3 [/home/dccmx/projects/console/test] 80,704,867 test.c:f2 [/home/dccmx/projects/console/test] 41,938,337 test.c:f1 [/home/dccmx/projects/console/test]
有没有更给力的图形前端呢?有,将callgrind.out.***用kcachegrind打开看看: