Почему приложения, скомпилированные GCC, всегда содержат символ _mcount?

Библиотеки не всегда содержат символ _mcount, в отличие от приложений (это можно проверить с помощью gobjdump или утилиты nm). Я читал, что _mcount используется для реализации профилирования, но символ присутствует, даже когда профилирование отключено и включена оптимизация (-O2). Служит ли он какой-то другой дополнительной цели?

Обновление: я на Solaris, так что это компоновщик Solaris в сочетании с GCC, я не уверен, имеет ли это значение или нет. Версия GCC — 4.2.2. Это происходит, даже если я компилирую файл, содержащий только код int main() { return 0; } без связанных библиотек.

Обновление 2: я набираю:

$ g++ -O2 mytest.cpp
$ nm a.out | grep _mcount
[65]    | 134547444|       1|FUNC |GLOB |0    |11     |_mcount

И g++ ни к чему не привязан. Кроме того, я попытался скомпилировать с помощью компилятора sun CC, и у него нет этой проблемы. Я также пытался обновить GCC, символ все еще существует в 4.4.1.


person Joseph Garvin    schedule 08.01.2010    source источник
comment
В вашей системе случайно не используется gcc (или команда, которую вы используете) с псевдонимом чего-то, что вызывает компилятор с некоторыми параметрами по умолчанию, не так ли? Можете ли вы опубликовать точные вызовы, которые вы используете для компиляции?   -  person Chris Lutz    schedule 08.01.2010
comment
Псевдонима нет, сообщение обновляется командами.   -  person Joseph Garvin    schedule 08.01.2010


Ответы (4)


Хм. странно, на моей машине (ubuntu 9.10) такого не происходит.

Для теста я просто составил небольшое приветственное слово:

#include <stdio.h>

int main (int argc, char **args)
{
  printf ("hello world\n");
}

скомпилировано с

gcc test.c

У него не было символа _mcount. Я проверил с:

nm a.out | grep -i count

Пробуя некоторые ключи компилятора (-g, -pg и т. д.), оказывается, что символ появляется только в том случае, если вы компилируете свое приложение с параметром -pg. В этом случае вы компилируете с включенным профилированием, поэтому символ _mcount имеет причину для существования.

person Nils Pipenbrinck    schedule 08.01.2010
comment
Я обновил свой пост, чтобы уточнить, что я не указываю pg, но это все еще происходит. Интересно, в чем разница... - person Joseph Garvin; 08.01.2010

Вы связываетесь с библиотекой, в которой включено профилирование? Это притянет _mcount.

person Emerick Rogul    schedule 08.01.2010

Для информации,

В моем Linux-боксе (Archlinux x86), GCC 4.4.2 запуск nm на a.out дает:

$ nm ./a.out 
08049594 d _DYNAMIC
08049680 d _GLOBAL_OFFSET_TABLE_
0804852c R _IO_stdin_used
         w _Jv_RegisterClasses
08049584 d __CTOR_END__
08049580 d __CTOR_LIST__
0804958c D __DTOR_END__
08049588 d __DTOR_LIST__
0804857c r __FRAME_END__
08049590 d __JCR_END__
08049590 d __JCR_LIST__
080496a0 A __bss_start
08049698 D __data_start
080484e0 t __do_global_ctors_aux
080483d0 t __do_global_dtors_aux
0804969c D __dso_handle
         w __gmon_start__
         U __gxx_personality_v0@@CXXABI_1.3
080484da T __i686.get_pc_thunk.bx
08049580 d __init_array_end
08049580 d __init_array_start
08048470 T __libc_csu_fini
08048480 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
080496a0 A _edata
080496a8 A _end
0804850c T _fini
08048528 R _fp_hw
08048324 T _init
080483a0 T _start
080496a0 b completed.5829
08049698 W data_start
080496a4 b dtor_idx.5831
08048430 t frame_dummy
08048460 T main

и запуск ldd на a.out дает

$ ldd ./a.out 
linux-gate.so.1 =>  (0xb77b1000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb769b000)
    libm.so.6 => /lib/libm.so.6 (0xb7675000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb7658000)
    libc.so.6 => /lib/libc.so.6 (0xb7511000)
    /lib/ld-linux.so.2 (0xb77b2000)

Попробуйте выяснить, была ли одна из зависимых библиотек собрана с поддержкой профилирования, запустив для них nm. Как сказал @Emerick, это потянет _mcount.

person Gregory Pakosz    schedule 11.01.2010
comment
Я не связываю никакие библиотеки, см. мой оригинальный пост. - person Joseph Garvin; 12.01.2010
comment
ну g++ связывается с libc автоматически, попробуй - person Gregory Pakosz; 12.01.2010
comment
Интересно, пробовал, и в libc есть символ _mcount_newent, а _mcount нет. Остальные ничего не показывают при поиске _mcount. Все еще не объясняет, почему _mcount появится :/ Погуглив _mcount_newent, я получил некоторые неясные результаты исходного кода, но никаких хороших объяснений на английском языке. - person Joseph Garvin; 13.01.2010

Не полезно, но, возможно, информативно:

При новой установке OpenSolaris и g++ я вижу те же результаты.

На справочной странице для gcc/++ в OpenSolaris отмечается, что уровень отладочной информации по умолчанию — «2»… но изменение этого значения на 1 или 0 не устраняет символ _mcount.

Если я компилирую с cc-5.0, символ _mcount отсутствует. (хотя при компиляции с cc это просто псевдоним/оболочка для gcc).

В Ubuntu и Fedora символ отсутствует, если компилируется с параметром -pg (в этом случае символом является mcount, а не _mcount).

person SuperMagic    schedule 14.01.2010
comment
Это очень интересно, я могу поместить это в отчет об ошибке для разработчиков GCC, проголосовал за :) - person Joseph Garvin; 15.01.2010