11

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

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

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

提前致谢。

4

7 回答 7

9

我已经设法解决了问题,至少令我满意,并且想把我发现的东西传递出去。

使用 readelf (readelf -a -W) 我创建了一个报告,列出了两个构建的内容并比较了它们(使用 Beyond Compare)。这表明从 boost 库中提取了几个额外的符号。

瞧,我们实际上是针对不同版本的依赖库构建的,但没有意识到这一点。在这种情况下不会造成任何伤害,但最好知道可执行文件中的内容。

感谢大家的周到答复。

于 2009-08-14T17:22:41.560 回答
8

objdump可能是您正在寻找转储二进制文件内容的程序。

objdump -h将向您显示部分及其大小,因此您应该能够看到发生大小变化的位置,然后进一步深入了解原因。

于 2009-08-14T13:49:59.150 回答
3

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

  • 您是否使用其他外部库?
  • 你是静态链接还是动态链接?
  • 您是否更改了 -O 或 -s 之类的标志?
于 2009-08-14T13:41:34.977 回答
1

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

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

于 2009-08-14T14:10:43.460 回答
1

以前有人问过这个问题,答案是编译器的内部状态在不同的编译器运行时可能会有所不同,这可能导致发出不同的代码,从而具有不同的大小。

于 2009-08-14T13:44:48.797 回答
0

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

于 2009-08-14T16:53:49.557 回答
0

在其他方面相同的构建之间存在大小差异的一个可能原因是二进制文件中可能存储了可变大小的信息。一些例子:

  • 编译器可能会放置有关编译中涉及的文件的路径/名称信息,用于调试信息或由于使用__FILE__宏。它可能出于自己的目的而这样做,与这些事情中的任何一个都无关。如果构建发生在具有稍微不同目录结构的不同机器上,这可以解释二进制文件中的差异。
  • 类似的构建日期/时间,虽然我希望这些会更少地进入二进制文件(但我知道什么?)。如果这是一个促成因素,即使在同一台机器上的相同版本中,您也会看到不同的尺寸,只是在不同的足够时间。

正如 Neil Butterworth 指出的那样,这些事情归结为构建机器状态的差异。

于 2009-08-14T16:54:58.900 回答