5

After a long sequence of debugging I've narrowed my problem down to one file. And the problem is that the file compiles differently in two different directories, when everything else is the same.

I'm using CodeSourcery's arm gcc compiler (gcc version 4.3.3, Sourcery G++ Lite 2009q1-161) to compile a simple file. I was using it in one module with no issues and then I copied it to another module to use there. When it compiles, the object file is significantly different. The command line to compile the two files is identical (I used the linux history to make sure), and the 3 include files are also identical copies (checked with diff).

I did a binary compare on the two object files and they have a lot of individual byte differences scattered around. I did an objdump -D of both and compared them and there are a lot of differences. Here is dump1, dump2, and the diff. The command line is " arm-none-eabi-gcc --std=gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o".

How is this possible? I've also compiled with -S instead of -c and looked at the assembler output and that's identical except for the directory path. So how can the object file be different?

My real problem is that when I try to link the object file for dump2 into my program, I get undefined reference errors, so something in the object is wrong, whereas the object for dump1 gets no such errors and links fine.

JonS
  • 621
  • 7
  • 25
  • 1
    Apparently there is a tag [tag:binary-reproducibility] for this. I have seen the same thing with this compiler. The majority of the *diff* shows different register selection or file offsets, but it has the same basic functionality. See: [Debian reproducible builds](https://wiki.debian.org/ReproducibleBuilds). Of course it is possible that the output is different. Is it your problem? I think that your issue is something else. – artless noise Jun 10 '14 at 21:59
  • Also: [SO binary changing in each build](http://stackoverflow.com/questions/4140329/binary-object-file-changing-in-each-build), etc. – artless noise Jun 10 '14 at 22:06
  • You might try compiling with `-O0` to see if the differences persist. – markgz Jun 10 '14 at 22:07
  • I have a similar issue [on ARM](http://stackoverflow.com/questions/21225386/yagarto-gcc-win32-compiles-same-code-differently-on-different-pcs). Exact same code and compiler, slightly different assembly generated in each case (different register selection). It's as if the optimization is affected by some random memory issue or some timing issue. – M.M Jun 10 '14 at 22:34
  • Note that in this case everything in the diff looks to be from the .debug_* sections. I know nothing about the DWARF format, but when I see nonsense "instructions" where no bytes have the top bit set and the sequence 2e 2e 2f is scattered about I know I'm looking at ASCII path strings. I'll bet the bulk of the difference is simply down to having compiled in a different location. Does it work if you compile without debug info? – Notlikethat Jun 10 '14 at 22:45
  • @Notlikethat Yes, the differences seem to be in the DWARF file offsets (maybe even a source location?). I have seen this compiler (at least 2009q? version of *arm-none-eabi-gcc*) select different registers; but achieves the same functionality. Ie, `int a` -> r4 and `int b` -> r5 on one run and then swapped on another. Timestamps, build-ids, un-initialized code sections (for alignment), etc can all cause binary differences. – artless noise Jun 11 '14 at 01:27

2 Answers2

2

For large scale software, there are many implementations are doing hashing on pointers. This is one major reason that cause result randomization. Usually if the program logic is correct, the order of some internal data structures could be different which is not harmful in most cases.

And also, don't compare the 'objdump -D' output, since your are compiling the code from different directory, the string table, symbol table, DWARF or eh_frame should be different. You will certainly get lots of diff lines.

The only comparison that makes sense is to compare the output of 'objdump -d' which only takes care of the text section. If text section is same(similar) then it can be considered as identical.

1

Most likely your file picks up different include files. This this the most likely reason.

Check that your include paths are exactly the same, paths in the include statements. They may point to different directories. C and C++ has a feature that when you #include abcd.h it tries to load abcd.h from the directory of the calling file. Check this.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51