为什么GCC编译的应用程序总是包含_mcount符号?

为什么GCC编译的应用程序总是包含_mcount符号?,gcc,profiling,shared-libraries,symbols,Gcc,Profiling,Shared Libraries,Symbols,库并不总是包含_mcount符号,但应用程序包含(您可以使用gobjdump或nm实用程序验证这一点)。我已经读到_mcount用于实现评测,但即使禁用评测并启用优化(-O2),符号仍然存在。它还有其他用途吗 更新:我在Solaris上,所以这是结合了GCC的Solaris链接器,我不确定这是否有区别。GCC版本为4.2.2。即使我编译了一个只包含代码int main(){return 0;}且没有链接库的文件,也会发生这种情况 Update2:I类型: $ g++ -O2 mytest.cpp

库并不总是包含_mcount符号,但应用程序包含(您可以使用gobjdump或nm实用程序验证这一点)。我已经读到_mcount用于实现评测,但即使禁用评测并启用优化(-O2),符号仍然存在。它还有其他用途吗

更新:我在Solaris上,所以这是结合了GCC的Solaris链接器,我不确定这是否有区别。GCC版本为4.2.2。即使我编译了一个只包含代码
int main(){return 0;}
且没有链接库的文件,也会发生这种情况

Update2:I类型:

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

g++没有任何别名。另外,我尝试使用sun CC编译器进行编译,但它没有这个问题。我还尝试过更新GCC,符号仍然存在于4.4.1中。

Hm。奇怪的是,在我的机器(ubuntu 9.10)上,这并没有发生

为了进行测试,我刚刚编译了一个小hello单词:

#include <stdio.h>

int main (int argc, char **args)
{
  printf ("hello world\n");
}
它没有_mcount符号。我查过:

nm a.out | grep -i count

尝试一些编译器开关(-g,-pg等)。结果表明,只有在使用-pg编译应用程序时,才会出现该符号,在这种情况下,您是在启用分析的情况下编译的,因此_mcount符号存在的原因。

您是否链接到启用分析的库?这将吸引更多的信息

在我的Linux机器(Archlinux x86)上,GCC4.4.2在
a.out
上运行
nm
,给出了:

$ 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
a.out
上运行
ldd
,可以

$ 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所说,这将带来
\u mcount

没有帮助,但可能会提供信息:

在新安装的OpenSolaris和g++上,我看到了相同的结果

在OpenSolaris上的gcc/++手册页中,它注意到调试信息的默认级别为“2”。。。但将其更改为1或0并不能消除_mcount符号

如果使用cc-5.0编译,则不存在_mcount符号。(尽管使用cc进行编译,但这是因为cc只是gcc的别名/包装器)


在Ubuntu和Fedora上,符号不存在,除非使用-pg选项编译(在这种情况下,符号是mcount而不是_mcount)。

我更新了我的帖子,澄清我没有指定pg,但它仍然存在。不知道有什么区别……您的系统没有将
gcc
(或您正在使用的命令)别名为使用某些默认开关调用编译器的对象,是吗?你能发布你用来编译此文件的确切调用吗?没有别名,用命令更新。我没有链接任何库,请参阅我的原始帖子。好的
g++
自动链接
libc
,试试它有趣,我试过了,libc有一个符号“mcount newent”,但没有“mcount”。其他人在搜索时什么也没显示。仍然没有解释为什么会出现_mcount:/google搜索_mcount\u newent我得到了一些模糊的源代码结果,但没有很好的英语解释。这很有趣,我可以把它放在GCC开发人员的错误报告中,upvoted:)
$ 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)