Sha*_*awn 5 profiling valgrind callgrind
我分析了一些在 Linux 上运行的非常简单的 C++ 程序。main() 的包含成本远非 100%,大约为 3.83%。我是否正确使用了 callgrind?我在下面粘贴了callgrind_annotatewith的输出--inclusive=yes。
该程序称为堆,它执行简单的堆排序。我使用的命令是
valgrind --tool=callgrind ./heap
Run Code Online (Sandbox Code Playgroud)
然后,我输入
callgrind_annotate --inclusive=yes callgrind.out.25434
Run Code Online (Sandbox Code Playgroud)
输出:
`--------------------------------------------------------------------------------
Profile data file 'callgrind.out.25434' (creator: callgrind-3.6.0)
`--------------------------------------------------------------------------------
I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 361578
Trigger: Program termination
Profiled target: ./heap (PID 25434, part 1)
Events recorded: Ir
Events shown: Ir
Event sort order: Ir
Thresholds: 99
Include dirs:
User annotated:
Auto-annotation: off
`--------------------------------------------------------------------------------
Ir
`--------------------------------------------------------------------------------
2,552,558 PROGRAM TOTALS
`--------------------------------------------------------------------------------
Ir file:function
`--------------------------------------------------------------------------------
2,552,558 ???:0x00000810 [/lib/ld-2.7.so]
2,515,793 ???:0x00000a60 [/lib/ld-2.7.so]
2,515,219 ???:0x00015270 [/lib/ld-2.7.so]
2,514,780 ???:0x000021e0 [/lib/ld-2.7.so]
2,456,164 ???:0x0000b2f0 [/lib/ld-2.7.so]
2,256,719 ???:0x00009e40 [/lib/ld-2.7.so]
1,702,371 ???:0x00009ac0 [/lib/ld-2.7.so]
657,883 ???:0x000098e0 [/lib/ld-2.7.so]
367,045 ???:0x00017040 [/lib/ld-2.7.so]
33,170 ???:0x080483e0 [/home/test/heap]
33,036 ???:0x0000ce60 [/lib/ld-2.7.so]
31,347 ???:0x0000e850 [/lib/ld-2.7.so]
30,706 ???:(below main) [/lib/libc-2.7.so]
30,071 ???:0x00008570 [/lib/ld-2.7.so]
27,954 ???:0x0000f500 [/lib/ld-2.7.so]
27,758 ???:0x0000ca30 [/lib/ld-2.7.so]
21,366 ???:0x0001767b [/lib/ld-2.7.so]
Run Code Online (Sandbox Code Playgroud)
在main()不调用图上的功能。_startglibc 中有一个函数,它会调用main()并且从main. 还有(对于动态链接的程序 = 几乎所有)一个 ELF 解释器,也称为动态链接器(运行时):/lib/ld-linux.so(这个名字在 linux 中使用,在其他 Unix 中使用类似 /lib /ld.so)。链接器将加载并初始化应用程序所需的所有动态库;并且它之前被操作系统调用_start。
之前做了什么main?库的加载(打开库文件,解析它的头文件,映射它,在内存中采用新位置的代码=重定位处理),以及它们的初始化(动态和静态链接的库都需要这个;注意 glibc=libc 也是库) . 每个库都可能有一个代码,它会在加载库(__attribute__((constructor))或全局对象的非平凡构造函数)后立即启动。另外,glibc 可以注册一些在 main 之后运行的函数(例如 via atexit(); 如果 main 正常返回,它们将被 _start 调用),并且库可能具有全局对象的析构函数。
如果您的程序使用线程,则线程1..的顶级函数n将不是主函数(每个线程可以单独堆栈;并且函数调用链main存储在线程 0 的堆栈中)。
在您的示例中,我们看到 /lib/ld-*.so,它是一个动态链接器。看起来,您的应用程序执行时间太短而无法正确分析,并且它使用了大量动态库。