Код, скомпилированный с флагом профилирования, не генерирует gmon.out

Я скомпилировал код с помощью gcc, используя флаг профилирования (-pg), но когда я запускаю программу, gmon.out не генерируется.
Я скомпилировал тестовый код — на самом деле, код из < href="https://stackoverflow.com/questions/19826735/gmon-out-isnt-created-when-i-compile-with-pg-flag-with-g">этот вопрос -- на посмотрите, работают ли флаг компиляции и 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 не написано после компиляции с помощью gcc -pg -g , и это не дублирование, если только я полностью не понял это.


person Brandt    schedule 23.11.2014    source источник
comment
У меня была точно такая же проблема. Отличное описание проблемы и ответ!   -  person brokenfoot    schedule 18.05.2016


Ответы (1)


Вы не передаете -pg при создании исполняемого файла.

i.e.

gcc -o xrttimetag xrttimetag.o ....

Вы также должны передать здесь опцию -pg. Я могу воспроизвести проблему (т. е. символы не определены для вызовов gmon*), если я использую -pg при компиляции, но не при компоновке.

Из документации gcc:

-pg

Сгенерируйте дополнительный код для записи информации профиля, подходящей для программы анализа gprof. Вы должны использовать эту опцию при компиляции исходных файлов, о которых вы хотите получить данные, а также при компоновке.

person P.P    schedule 23.11.2014
comment
Идеально. Спасибо! Просто в дополнение к ответу: в моем случае, когда я использую старый добрый GNU Make и не хочу изменять make-файлы, в процесс удержания был добавлен флаг -pg через (переменная среды) CFLAGS (для объекта (.o) генерация) и LDFLAGS для этапа компоновки. - person Brandt; 24.11.2014