August 11th, 2003, 04:35 PM
Same build, different checksums ??
I am using gcc v2.96 on Linux to compile, and some of my resulting .o files have a different checksum every time. Here is an ascii dump diff of two of the same .o files, built within minutes of each other on the same machine, but have different checksums. I have included +- 8 lines of context with the diff:
As you can see, its the "cppqwuz2c" line that changes to "cppLWW03b" that's causing the checksum change. If I run the build again, it will be some new "cpp<randomtext>" sequence of characters to throw off the checksum again.
Does anyone know what can be causing this or seen something like it before? This is happening in just several of my .o files across a project with hundreds of .o's whose checksums are the same every time, so the compiler is probably working right.
Thanks a great deal in advance for any help!
--Brian E. Bianchi
August 12th, 2003, 08:12 AM
I'd guess that the code being compiled uses the __TIME__ and/or __DATE__ predefined macros. Those macros expand to a string that contains the compile time and date respectively.
On some systems, the object file format is actually required to contain a time stamp. IIRC, that's not the case with gcc under Linux, but that's another possible explanation of the behaviour you're seeing.
August 13th, 2003, 08:43 AM
Thanks for you response, but I still don't get it. Where are the __TIME__ and __DATE__ values you quote coming from? Why does this happen with only just a few object files out of a hundred or so that make up my project's build?
How would I go about stopping this from happening so I can get a consistent checksum? Is the problem in the code somewhere, or the compiler?
August 13th, 2003, 09:20 AM
I thought it might be one of these macros as well... but looking at the code, it doesn't look like it. I would suggest reading through the ELF binary format... and look for variable values, like build times, etc. The macros mentioned __FILE__ simply are in the code, and just like any macro, are replaced by the preprocessor.
August 13th, 2003, 09:34 AM
As I see it... if you got the same checksum across builds, that would defeat the point of the checksum in the first place. Being able to release a build and say, here is the checksum, allows people to verify that someone else didn't come around and build it again... etc.
August 13th, 2003, 09:40 AM
My bosses want two equal builds to result in two equal checksums. And when it doesn't happen, they want to know why :-(
August 13th, 2003, 09:41 AM
Do a g++ -E twice and do a diff on the output... that will at least rule out the preprocessor.
August 13th, 2003, 10:04 AM
I did as you suggested and the output from the g++ -E is the same in consecutive builds. The checksums of two object files from consecutive builds that results when I don't use the -E, are not :-(
So I have ruled out the preprocessor. Thanks a great deal for that suggestion. Are there any other possibilities I might look into?
I'm at wits end on this one.
August 13th, 2003, 10:59 AM
I ran gcc with a "-v" and came up with something interesting. I am including the output below, although 99% of it is probably useless info. What is important, is the very last line, where a file in /tmp is referenced.
gcc -v -c -g -D CT_LINUX -D linux -D LINUX -pthread -D _STLP_NO_OWN_IOSTREAMS=1 -D _PTHREADS=1 -D USING_STLPORT -D_STLP_USE_NEWALLOC -D_STLP_USE_MALLOC -DSR_DEBUG -DNOTICE -DSETS -DEMANATE -DSUBAGENT -DLINUX -DMIBDEFS=\"SpdTrapsdefs.h\" -DMIBPART=\"SpdTrapspart.h\" -DMIBSUPP=\"SpdTrapssupp.h\" -DMIBTYPE=\"SpdTrapstype.h\" -DMIBOID=\"SpdTrapsoid.c\" -DSR_UDS_IPC -DSR_TRANSPORT_TABLE -DSR_SNMPv2c_PACKET -DSR_SNMPv1_WRAPPER -DSR_SNMPv2_PDU -DSR_NOTIFY_FULL_COMPLIANCE -DSR_SNMP_ADMIN_MIB -DSR_GENERATE_CONFIGURATION -DSR_MIB_TABLE_HASHING -DSR_CONFIG_FP -DSR_IP -I ../../../BaseSvcs/../cakits/STLport/stlport -I ../../../BaseSvcs/../cakits/ACE/ACE_wrappers -I ../../../BaseSvcs/../BaseSvcs/export/include -I ../../../BaseSvcs/../BaseSvcs/export/include/smap -I ../../../BaseSvcs/../OMAP/export/include -I ../../../BaseSvcs/../OMAP/code/LNXAlarmSubAgent -I ../../../BaseSvcs/../ThirdParty/emanate/snmp22.214.171.124/include -I ../../../BaseSvcs/../cakits/inflection-components/Util/include -I ../../../BaseSvcs/../cakits/inflection-components/Interfaces/include -fPIC SpdTrapsoid.c
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2)
/usr/lib/gcc-lib/i386-redhat-linux/2.96/cpp0 -lang-c -v -I ../../../BaseSvcs/../cakits/STLport/stlport -I ../../../BaseSvcs/../cakits/ACE/ACE_wrappers -I ../../../BaseSvcs/../BaseSvcs/export/include -I ../../../BaseSvcs/../BaseSvcs/export/include/smap -I ../../../BaseSvcs/../OMAP/export/include -I ../../../BaseSvcs/../OMAP/code/LNXAlarmSubAgent -I ../../../BaseSvcs/../ThirdParty/emanate/snmp126.96.36.199/include -I ../../../BaseSvcs/../cakits/inflection-components/Util/include -I ../../../BaseSvcs/../cakits/inflection-components/Interfaces/include -D__GNUC__=2 -D__GNUC_MINOR__=96 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__NO_INLINE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_i386__ -D__PIC__ -D__pic__ -D_REENTRANT -D CT_LINUX -D linux -D LINUX -D _STLP_NO_OWN_IOSTREAMS=1 -D _PTHREADS=1 -D USING_STLPORT -D_STLP_USE_NEWALLOC -D_STLP_USE_MALLOC -DSR_DEBUG -DNOTICE -DSETS -DEMANATE -DSUBAGENT -DLINUX -DMIBDEFS="SpdTrapsdefs.h" -DMIBPART="SpdTrapspart.h" -DMIBSUPP="SpdTrapssupp.h" -DMIBTYPE="SpdTrapstype.h" -DMIBOID="SpdTrapsoid.c" -DSR_UDS_IPC -DSR_TRANSPORT_TABLE -DSR_SNMPv2c_PACKET -DSR_SNMPv1_WRAPPER -DSR_SNMPv2_PDU -DSR_NOTIFY_FULL_COMPLIANCE -DSR_SNMP_ADMIN_MIB -DSR_GENERATE_CONFIGURATION -DSR_MIB_TABLE_HASHING -DSR_CONFIG_FP -DSR_IP SpdTrapsoid.c /tmp/ccAdFk8L.i
The "/tmp/ccAdFk8L.i" reference actually is embedded in the .o file that results from this build, causing the checksum to be different every time. Here is an except:
Next time I run the build, the /tmp file will be different. What is generating that /tmp/ccAdFk8L.i file and why is it embedded in the object file? Any help?
August 13th, 2003, 11:27 AM
The /tmp/*.i file is the resulting preprocessor file. You should be able to do a two step compilation, make the .i file yourself with whatever name you want. I'm using gcc 2.95.1 and it doesn't seem to include the TMPDIR files in the symbol table... you may want to find a compiler newsgroup and ask them what a better solution would be.
I have to take care of something... but I'll see what I can find in a bit.