【发布时间】:2014-06-10 21:51:55
【问题描述】:
经过一长串调试后,我将问题缩小到一个文件。问题是文件在两个不同的目录中编译不同,而其他一切都相同。
我正在使用 CodeSourcery 的 arm gcc 编译器(gcc 版本 4.3.3,Sourcery G++ Lite 2009q1-161)来编译一个简单的文件。我在一个模块中使用它没有问题,然后我将它复制到另一个模块以在那里使用。编译时,目标文件明显不同。编译这两个文件的命令行是相同的(我用linux历史来确定),3个包含文件也是相同的副本(用diff检查)。
我对两个目标文件进行了二进制比较,它们散布着很多单独的字节差异。我做了一个 objdump -D 并比较了它们,有很多不同之处。这是dump1、dump2 和diff。命令行是“ arm-none-eabi-gcc --std=gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o"。
这怎么可能?我还使用 -S 而不是 -c 进行了编译,并查看了汇编程序的输出,除了目录路径之外,它是相同的。那么目标文件怎么会不一样呢?
我真正的问题是,当我尝试将 dump2 的目标文件链接到我的程序时,我得到未定义的引用错误,因此对象中的某些内容是错误的,而 dump1 的对象没有出现此类错误并且链接正常。
【问题讨论】:
-
显然有一个标签binary-reproducibility。我在这个编译器上看到了同样的事情。大多数 diff 显示不同的寄存器选择或文件偏移,但它具有相同的基本功能。请参阅:Debian reproducible builds。当然,输出可能不同。是你的问题吗?我认为您的问题是另一回事。
-
您可以尝试使用
-O0进行编译以查看差异是否仍然存在。 -
我有一个类似的问题on ARM。完全相同的代码和编译器,在每种情况下生成的程序集略有不同(不同的寄存器选择)。就好像优化受到一些随机内存问题或一些时间问题的影响。
-
请注意,在这种情况下,差异中的所有内容看起来都来自 .debug_* 部分。我对 DWARF 格式一无所知,但是当我看到没有字节设置最高位并且序列 2e 2e 2f 分散在各处的废话“指令”时,我知道我正在查看 ASCII 路径字符串。我敢打赌,大部分差异只是因为在不同的位置编译。如果您在没有调试信息的情况下进行编译,它是否可以工作?
标签: c linux gcc compiler-construction arm