c++ - 使用分析标志编译的代码不会生成 gmon.out

标签 c++ c gcc profiling gprof

我使用分析标志 (-pg) 用 gcc 编译了一个代码,但是当我运行该程序时,没有生成 gmon.out。
我编译了一个测试 代码 -- 实际上,是来自 this 的代码问题 -- 查看编译标志和 gprof 是否有效,是的,它有效。

为了编译代码(名为 xrttimetag),使用了以下行(下面我使用了 -I(...)-L(. ..) 以隐藏大量指向其他科学图书馆的路径):

gcc -c  -o ./xrttimetag.o  -Wall --pedantic -Wno-comment -Wno-long-long -pg -fPIC -I(...) -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" -DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE_URL="" -Dg77Fortran=1 -DgFortran=1 -DHAVE_CONNECT=1 -DHAVE_ACCEPT=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_LIBM=1 -DHAVE_LIBDL=1 -DHAVE_LIBNCURSES=1 -DSIZEOF_LONG=8 xrttimetag.c

gcc -o xrttimetag xrttimetag.o      -L(...) -lswxrt -latFunctions3.3 -lcoordfits -lcoord -lephemeris -lhdinit_2.7 -lhdutils_2.7 -lape_2.8 -lcfitsio_3.37 -lreadline -lhdio_2.7 -lncurses -ldl -lm  -L/usr/lib64/gcc/x86_64-suse-linux/4.6 -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../.. -L/usr/lib64/gcc/x86_64-suse-linux/4.6 -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.6/../../.. -lgfortran -lm -lgcc_s -lgcc -lquadmath -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc 

我在生成的二进制文件中寻找与 gmon 相关的符号,它们对我来说有点奇怪,因为它们是 undefined :

readelf -s `which xrttimetag` | egrep "gmon|mcount"
 21: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
 74: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mcount@GLIBC_2.2.5 (2)
 41: 000000000040267c     0 FUNC    LOCAL  DEFAULT   15 call_gmon_start
 96: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
166: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mcount@@GLIBC_2.2.5

另一方面,test代码,我编译了:

g++ -pg test.cpp

搜索“gmon|mcount”符号给我:

readelf -s test | egrep "gmon|mcount"
 6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mcount@GLIBC_2.2.5 (3)
11: 0000000000400850    63 FUNC    GLOBAL DEFAULT   15 __gmon_start__
40: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS gmon-start.c
43: 0000000000400890     0 FUNC    LOCAL  DEFAULT   15 call_gmon_start
73: 0000000000400850    63 FUNC    GLOBAL DEFAULT   15 __gmon_start__
91: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mcount@@GLIBC_2.2.5

我们可以确定“gmon”符号是为_test_代码而不是_xrttimetag_定义的,但我真的不明白为什么。我错过了什么?

谢谢。

PS:看到问题了gmon.out is not written after compiling with gcc -pg -g ,这一个不是重复的,除非我完全误解了那个。

最佳答案

生成可执行文件时没有传递 -pg

gcc -o xrttimetag xrttimetag.o ....

你也应该在这里传递 -pg 选项。如果我在编译时使用 -pg 但在链接时不使用,我可以重现问题(即符号未定义用于 gmon* 调用)。

来自gcc documentation :

-pg

Generate extra code to write profile information suitable for the analysis program gprof. You must use this option when compiling the source files you want data about, and you must also use it when linking.

关于c++ - 使用分析标志编译的代码不会生成 gmon.out,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27088861/

相关文章:

c++ - MSVC 2015/Wall 有很多无用的消息

c - 基于 epoll 的服务器中的空闲连接超时

c - 我用 C 编写的库的最佳实践

c - 标准行为与 gcc 版本有关吗?

c - 在C89中, 'old-style'函数定义中函数名的范围是什么?

c++ - Win32 C++ 中的无锁双端队列

c++ - C++ vector 的 size() 和 capacity()

c++ - 为什么迭代器不依赖于分配器? (也就是说,让迭代器变得可怕不会违反分配器的 typedef 抽象吗?)

c - 是否有动态检查实用程序可以标记结构中静态缓冲区的溢出?

c - 如何使用具有可变数量参数的标记粘贴运算符?