Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do applications compiled by GCC always contain the _mcount symbol?

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.

like image 778
Joseph Garvin Avatar asked Jan 08 '10 16:01

Joseph Garvin


3 Answers

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.

like image 98
Nils Pipenbrinck Avatar answered Sep 27 '22 21:09

Nils Pipenbrinck


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

like image 39
Emerick Rogul Avatar answered Sep 27 '22 22:09

Emerick Rogul


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.

like image 20
Gregory Pakosz Avatar answered Sep 27 '22 23:09

Gregory Pakosz