18
votes

I compiled a code with gcc using the profiling flag (-pg), but when I run the program no gmon.out is generated.
I compiled a test code -- actually, the one from this question -- to see if the compilation flag & gprof were working and, yes, it worked.

To compile the code (named xrttimetag) the following line was used (here below I used -I(...) and -L(...) to hide a huge list of paths to other scientific libraries):

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 

I looked for symbols related to gmon on the generated binary and they look a bit strange for me since they are 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

On the other hand, the test code, I compiled with:

g++ -pg test.cpp

And the search for "gmon|mcount" symbols give me:

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

We can that the "gmon" symbols are well defined for the _ test_ code and not for the _ xrttimetag_, but I don't really understand why. What am I missing?

Thanks.

PS: I saw the question gmon.out is not written after compiling with gcc -pg -g , and this one is not a duplication, unless I had completely misunderstood that one.

1
I had the exact same problem.. Excellent problem description & answer !brokenfoot

1 Answers

28
votes

You are not passing -pg when generating executable.

i.e.

gcc -o xrttimetag xrttimetag.o ....

You should pass -pg option here too. I can re-produce the problem (i.e. symbols are undefined for gmon* calls) if I use -pg when compiling but not when linking.

From the 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.