views:

421

answers:

4

Libraries don't always contain 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.

+2  A: 

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.

Nils Pipenbrinck
I've updated my post to clarify that I'm not specifying pg, yet it still happens. Wonder what the difference is...
Joseph Garvin
+1  A: 

Are you linking with a library that has profiling enabled? That would pull in _mcount.

Emerick Rogul
Nope, see my update.
Joseph Garvin
+1  A: 

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.

Gregory Pakosz
I'm not linking any libraries, see my original post.
Joseph Garvin
well `g++` links with `libc` automatically, try it
Gregory Pakosz
Interesting, I tried, and the libc has a symbol _mcount_newent, but no _mcount. The others don't show anything while grepping for _mcount. Still doesn't explain why _mcount would show up :/ Googling for _mcount_newent I get some obscure source code results but no nice English explanations.
Joseph Garvin
+1  A: 

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).

SuperMagic
That is very interesting, I can put that in a bug report for the GCC devs, upvoted :)
Joseph Garvin