我分析了几个在Linux上运行的非常简单的C++程序。所有这些函数的main()的包含成本远不是100%,大约是3.83%。我是否正确地使用了callgrind?我在下面粘贴了callgrind_annotate和--inclusive=yes的输出。
我使用的命令是
valgrind --tool=callgrind ./heap然后,我输入
callgrind_annotate --inclusive=yes callgrind.out.25434输出:
`--------------------------------------------------------------------------------
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]发布于 2011-12-04 12:47:38
main()不是调用图中的顶级函数。在glibc中有一个_start函数,它将调用main()并从main中获取返回值。还有(对于几乎所有的动态链接程序) ELF解释器,也称为动态链接器(运行时):/lib/ld-linux.so (这个名称在linux中使用,在其他Unixes中使用,如/lib/ld.so)。链接器将加载和初始化应用程序所需的所有动态库;它在_start之前被操作系统调用。
在main之前做了什么?加载库(打开库文件,解析它的头文件,映射它,为memory=relocations处理中的新位置采用代码),以及它们的初始化(动态和静态链接库都需要这些;请注意,glibc=libc也是库)。每个库都可能有一个代码,这些代码将在加载库(__attribute__((constructor))或全局对象的非平凡构造函数)后立即启动。此外,glibc可以注册一些在main之后运行的函数(例如,通过atexit();如果main正常返回,它们将被_start调用),并且库可能有一个用于全局对象的析构函数。
如果您的程序使用线程,则线程的顶部函数1..n将不是main (每个线程可以分离堆栈;来自main的函数调用链存储在线程0的堆栈中)。
在您的示例中,我们看到/lib/ld-*.so,它是一个动态链接器。看起来,您的应用程序执行时间太短,无法正确分析,而且它使用了大量的动态库。
https://stackoverflow.com/questions/5018693
复制相似问题