Защо приложенията, компилирани от GCC, винаги съдържат символа _mcount?

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

Актуализация: Аз съм на Solaris, така че това е Solaris linker, комбиниран с GCC, не съм сигурен дали това има значение или не. GCC версията е 4.2.2. Това се случва дори ако компилирам файл, който съдържа само кода int main() { return 0; } без свързани библиотеки.

Update2: Пиша:

$ 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. Другите не показват нищо, докато grepping за _mcount. Все още не обяснява защо _mcount ще се появи :/ Гугъл за _mcount_newent Получавам някои неясни резултати от изходния код, но не и хубави английски обяснения. - person Joseph Garvin; 13.01.2010

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

При нова инсталация на OpenSolaris и g++ виждам същите резултати.

В страницата с ръководство за gcc/++ на OpenSolaris се отбелязва, че нивото по подразбиране на информацията за отстраняване на грешки е "2" ... но промяната на това на 1 или 0 не премахва символа _mcount.

Ако компилирам с cc-5.0, символът _mcount не присъства. (въпреки че компилирането с cc е тъй като cc е просто псевдоним/обвивка за gcc).

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

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