tags:

views:

411

answers:

9

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.

+2  A: 

A replicable example would help:

  • Do you use other external libraries?
  • Do you link statically or dynamically?
  • Did you change flags like -O or -s ?
Dirk Eddelbuettel
Compiler flags is the first thing that came to my mind as well. Especially something like -O.
Jon Tackabury
+2  A: 

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.

anon
Before the close-monkeys get all happy over this, I should point out that question was about getting different exe's when compiled on different (Windows-flavored) platforms. This question is about getting different exe's on the exact same platform with the exact same compiler.
T.E.D.
...that being said, the answer you gave there is indeed just a good here.
T.E.D.
Well, the platforms are supposed to be identical. (Everything is built off dedicated build servers). So, what we're trying to figure out is where that has gone wrong.
BillTorpey
Please read both posts - probably nothing has gone wrong. The compiler can conceivably be in different states for different runs on the same machine, depending what else is going on.
anon
Agreed. Most likely the only thing that has "gone wrong" is Bill and Co's expectations of how compilers behave.
T.E.D.
Well personally *my* expectation is that compilers behave deterministically, at least in terms of the output produced.
caf
+5  A: 

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.

caf
+1  A: 

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.

T.E.D.
I think it's pretty important that when you give the compiler the same source code and the same build settings, it always output the exact same executable, byte-for-byte.Otherwise, if there is a bug in the optimizer, you might end up with some builds "working" and some "not", based solely on the amount of RAM that happened to be free at the moment the executable was built.... truly a nightmare to debug! Even if the compiler was bug free, some of your builds would run faster than others, despite the source code being the same in all cases.
Jeremy Friesner
You might want this, but as TED and myself have pointed out, you can't have it.
anon
Care to provide a reference that shows that gcc has this broken behaviour, since that's what the OP's question is about?
caf
A: 

Are you linking together multiple object files? If so, do you see the deltas on a particular object file? All object files?

Rob Jones
A: 

In addition to the compiler you need to check the standard libraries you link against. Check their version and verify they have not changed.

Martin York
A: 

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:

  • the compiler may be putting path/name information about the files invoved in the compilation, either for debugging information or due to the use of the __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.
  • similarly for the date/time of the build, though I'd expect that these would find their way into the binary much less often (but what do I know?). If this were a contributing factor, you'd see different sized out even from identical builds on the same machine, just at different enuogh times.

These things boil down to differences in the state of the build machine, as Neil Butterworth pointed out.

Michael Burr
+1  A: 

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.

BillTorpey
A: 

This not an answer. However this shows that:

  • same C code

  • same compiler

  • different size of the object file

  • but always the same size in a given directory

Strange, isn't ?

My context is :

  • the same c code (echo.c)

  • in two different directories

  • the same gcc command : gcc -DHAVE_CONFIG_H -g -O2 -Wall -c echo.c

~/Desktop/efixo/trunk/openwrt/package/echo/src$ gcc -DHAVE_CONFIG_H -g -O2 -Wall -c echo.c

~/Desktop/efixo/trunk/openwrt/package/echo/src$ ls -l echo.*

-rwxrw-r-- 1 alarme alarme 1871 mai 23 16:34 echo.c

-rw-r--r-- 1 alarme alarme 6368 mai 23 22:27 echo.o

~/Desktop/fastcgi/fcgi-2.4.0/examples$ gcc -DHAVE_CONFIG_H -g -O2 -Wall -c echo.c

~/Desktop/fastcgi/fcgi-2.4.0/examples$ ls -l echo.*

-rw-rw-r-- 1 alarme alarme 1871 jui 28 1999 echo.c

-rw-r--r-- 1 alarme alarme 6356 mai 23 22:28 echo.o

Any new explaination ?

Regards

cuagn
Please create a question next time. in any case, the difference is probably due to gcc embedding pathnames in the debugging info, the files should be the same size if you run `strip` on them
Hasturkun
Sorry, you're right... :(THe good news is that, w/o the debug parameter (-g) the objects are the same. Tnks
cuagn