Why do applications compiled by GCC always contain the _mcount symbol?
Libraries don't always cont开发者_如何学Goain the _mcount symbol, but applications do (you can verify this with gobjdump or the nm utility). I've read that _mcount is used to implement profiling, but the symbol is present even when profiling is disabled and optimization is enabled (-O2). Does it serve some other additional purpose?
Update: I am on Solaris, so this is the Solaris linker combined with GCC, I'm not sure if that makes a difference or not. The GCC version is 4.2.2. This happens even if I compile a file that only contains the code int main() { return 0; }
with no libraries linked.
Update2: I type:
$ g++ -O2 mytest.cpp
$ nm a.out | grep _mcount
[65] | 134547444| 1|FUNC |GLOB |0 |11 |_mcount
And g++ is not aliased to anything. Also, I tried compiling with the sun CC compiler, and it doesn't have this issue. I also tried updating GCC, symbol still exists in 4.4.1.
Hm. strange, on my machine (ubuntu 9.10) this does not happen.
For a test I just compiled a small hello-word:
#include <stdio.h>
int main (int argc, char **args)
{
printf ("hello world\n");
}
compiled with
gcc test.c
It didn't has the _mcount symbol. I checked with:
nm a.out | grep -i count
Trying some compiler switches (-g, -pg ect.) it turns out that the symbol only appears if you compile your application with -pg, In this case you compile with profiling enabled, so the _mcount symbol has a reason to exist.
Are you linking with a library that has profiling enabled? That would pull in _mcount
.
For information,
On my Linux box (Archlinux x86), GCC 4.4.2, running nm
on a.out
gives:
$ 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
and running ldd
on a.out
gives
$ 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)
Try to figure out whether one of the dependent libraries has been built with profiling support by running nm
on them. As @Emerick said, this would pull in _mcount
.
Not helpeful, but perhaps informative:
On a fresh install of OpenSolaris and g++, I see the same results.
In the man page for gcc/++ on OpenSolaris it notes the default level of debuging information is "2" ... but changing that to 1 or 0 does not eliminate the _mcount symbol.
If I compile with cc-5.0 the _mcount symbol is not present. (though compiling with cc it is as cc is just an alias/wrapper for gcc).
On Ubuntu and Fedora the symbol is not present unless compiling with the -pg option (in which case the symbol is mcount rather than _mcount).
精彩评论