gcc编译的二进制文件有不同的大小?

时间:2009-08-14 13:36:55

标签: c++ linux gcc elf

如果在不同时间使用gcc构建相同的代码,则生成的二进制文件将具有不同的内容。好吧,我对此并不狂热,但就是这样。

但是,我最近遇到的情况是,使用相同版本的gcc构建的相同代码生成的二进制文件大小与先前版本不同(大约1900字节)。

有谁知道可能导致这些情况的原因是什么?这是某种ELF问题吗?是否有任何工具(除了ldd)可用于转储二进制文件的内容以查看究竟有什么不同?

提前致谢。

7 个答案:

答案 0 :(得分:9)

我已经设法解决问题,至少让我感到满意,并希望传递我发现的东西。

使用readelf,(readelf -a -W)我创建了一个报告,列出了两个版本的内容并对它们进行了比较(使用Beyond Compare)。这表明有一些额外的符号从升级库中被拉入。

瞧,事实上,我们正在构建一个不同版本的依赖库,并没有意识到它。在这种情况下没有伤害,但知道你的可执行文件中有什么是好的。

感谢所有人的深思熟虑的答复。

答案 1 :(得分:8)

objdump可能是您要转储二进制文件内容的程序。

objdump -h会显示各个部分及其大小,因此您应该能够看到尺寸变化发生的位置,然后深入了解原因。

答案 2 :(得分:3)

一个可复制的例子会有所帮助:

  • 您使用其他外部库吗?
  • 您是静态还是动态链接?
  • 您是否更改了-O或-s?
  • 等标志

答案 3 :(得分:1)

这有点像asked before,答案是编译器的内部状态在不同的编译器运行中可能会有所不同,这会导致发出不同的代码,从而具有不同的大小。

答案 4 :(得分:1)

DEC VMS编译器也曾经这样做过。原因是优化器可以更好地处理它必须使用的更多可用RAM。显然,每次编译时都很难获得完全相同数量的可用RAM。

我记得当时有些人对此感到震惊。对于喜欢通过区分生成的二进制文件来检查源更改的人来说尤其如此。我现在的建议是克服它。来源你可以“差异”。对于二进制文件,唯一的保证是从相同的源文件编译的两个可执行文件都会执行您告诉他们要执行的操作。

答案 5 :(得分:0)

除了编译器,您还需要检查链接的标准库。检查他们的版本并确认他们没有更改。

答案 6 :(得分:0)

其他相同版本之间大小不同的一个可能原因是二进制文件中可能存在可变大小的信息。一些例子:

  • 编译器可能会在编译中放入有关调用的文件的路径/名称信息,以用于调试信息或由于使用__FILE__宏。它可能会因为它自己的目的而与这些事情无关。如果构建发生在具有稍微不同的目录结构的不同机器上,则可以解决二进制文件中的差异。
  • 类似于构建的日期/时间,虽然我希望这些可以更少地找到进入二进制文件的方式(但我知道什么?)。如果这是一个影响因素,那么即使是在同一台机器上的相同构建中,您也会看到不同的大小,只是在不同的enuogh时间。

这些事情归结为构建机器状态的差异as Neil Butterworth pointed out