经过长时间的调试后,我将问题缩小到一个档案。问题是,当其他所有目录相同时,文件在两个不同的目录中编译的方式不同。
我使用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的对象没有得到这样的错误和链接。< / p>
答案 0 :(得分:1)
对于大型软件,有许多实现正在对指针进行散列处理。这是导致结果随机化的一个主要原因。通常,如果程序逻辑正确,某些内部数据结构的顺序可能不同,这在大多数情况下都是无害的。
而且,不要比较&#39; objdump -D&#39;输出,因为您正在编译来自不同目录的代码,所以字符串表,符号表,DWARF或eh_frame应该是不同的。你肯定会得到很多差异线。
唯一有意义的比较是比较&#39; objdump -d&#39;的输出。只关注文本部分。如果文本部分相同(相似),则可以认为它是相同的。
答案 1 :(得分:0)
您的文件很可能会选择不同的包含文件。这是最可能的原因。
检查include路径中的包含路径是否完全相同。他们可能指向不同的目录。 C和C ++有一个功能,当你#include abcd.h
它试图从调用文件的目录加载abcd.h
时。检查一下。