gcc 编译的二进制文件具有不同的大小?
如果使用 gcc 在不同时间构建相同的代码,则生成的二进制文件将具有不同的内容。 好吧,我对此并不热衷,但事实就是如此。
然而,我最近遇到了一种情况,即使用相同版本的 gcc 构建的相同代码生成的二进制文件的大小与先前构建的大小不同(大约 1900 字节)。
有谁知道可能导致这两种情况的原因是什么? 这是某种 ELF 问题吗? 是否有任何工具(除了 ldd 之外)可用于转储二进制文件的内容以查看到底有什么不同?
提前致谢。
If the same code is built at different times w/gcc, the resulting binary will have different contents. OK, I'm not wild about that, but that's what it is.
However, I've recently run into a situation where the same code, built with the same version of gcc, is generating a binary with a different size than a prior build (by about 1900 bytes).
Does anyone have any idea what may be causing either of these situations? Is this some kind of ELF issue? Are there any tools out there (other than ldd) that can be used to dump contents of binaries to see what exactly is different?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在其他方面相同的构建之间存在大小差异的一个可能原因是二进制文件中可能存储了可变大小的信息。 一些示例:
__FILE__
宏。 它可能会出于自己的目的而这样做,而与这些事情无关。 如果构建发生在不同的机器上,即使目录结构略有不同,这也可以解释二进制文件的差异。这些事情可以归结为构建机器状态的差异,Neil巴特沃斯指出。
One possible reason for a difference in size between otherwise identical builds is that there can be variable-sized information stored in the binary. Some examples:
__FILE__
macro. It's possible that it might do this for it's own purposes that have nothing to do with either of those things. If the build occurs on different machines with even a slightly different directory structure, this can account for differences in the binary.These things boil down to differences in the state of the build machine, as Neil Butterworth pointed out.
除了编译器之外,您还需要检查链接的标准库。 检查它们的版本并验证它们没有更改。
In addition to the compiler you need to check the standard libraries you link against. Check their version and verify they have not changed.
我已经设法把事情解决了,至少让我满意,并想传递我所发现的东西。
使用 readelf (readelf -a -W ),我创建了一个报告,列出了两个版本的内容并比较了它们(使用 Beyond Compare)。 这表明从 boost 库中提取了一些额外的符号。
你瞧,我们实际上是在针对不同版本的依赖库进行构建,但没有意识到这一点。 在这种情况下不会造成任何损害,但最好了解可执行文件中的内容。
感谢大家的周到回复。
I've managed to sort things out, at least to my satisfaction, and wanted to pass along what I've found.
Using readelf, (readelf -a -W ) I created a report listing contents of both builds and compared them (using Beyond Compare). This showed that a couple of extra symbols were getting pulled in from boost libs.
Lo and behold, we were in fact building against a different version of a dependent library and didn't realize it. No harm done in this case, but it's good to know what's going into your executable.
Thanks to all for the thoughtful replies.
objdump
可能是您正在寻找的用于转储二进制文件内容的程序。objdump -h 将向您显示各个部分及其大小,因此您应该能够看到大小发生变化的位置,然后进一步深入了解原因。
objdump
is probably the program you are looking for to dump the contents of binaries.objdump -h
will show you the sections and their sizes, so you should be able to see where the size change is happening and then drill down further to see why.一个可复制的示例会有所帮助:
A replicable example would help:
之前曾被问过,答案是内部状态编译器在不同的编译器运行中可能会有所不同,这可能会导致发出不同的代码,从而具有不同的大小。
This has been sort of been asked before, and the answer is that the internal state of the compiler may well be different on different compiler runs, which can result in different code been emitted and thus having different size.
DEC VMS 编译器也曾经这样做过。 原因是优化器可以使用更多的可用 RAM 来完成更好的工作。 显然,每次编译时都很难拥有完全相同数量的可用 RAM。
我记得当时有些人对此感到震惊。 对于那些喜欢通过比较生成的二进制文件来检查源代码更改的人来说尤其如此。 我当时和现在的建议都是克服它。 您可以“比较”的来源。 对于二进制文件,唯一的保证是从同一源文件编译的两个可执行文件都会执行您告诉它们执行的操作。
The DEC VMS compilers used to do this too. The reason is that the optimizer could do a better job the more free RAM it had to work with. Obviously it is very difficult to have the exact same amount of free RAM available every time you compile.
I remember at the time some people were appalled by this. This was particularly the case for folks who liked to check for source changes by diff-ing the resulting binaries. My advice then as now is to get over it. Sources you can "diff". For binaries the only guarantee is that both executables compiled from the same source files will do what you told them to do.