title: GCC .obj file output is not deterministic (.debug_info, PROGBITS section)
body: <p>My compile command is<br>
  <code>C:\work\PROJ-test\QNX_SDK\host\win32\x86/usr/bin/qcc -c -Wc,-frandom-seed="sadfsasafssadsa" -Wc,-MP,-MT,C:/work/PROJ-test/N_Manag/src/bld/N_Manag//armle-v7/release/nav_event_rcv.cpp.o,-MMD,C:/work/PROJ-test/N_Manag/src/bld/N_Manag//armle-v7/release/nav_event_rcv.cpp.d -Vgcc_ntoarmv7le -w9 -shared  -O3  -ggdb3 -DBUILD_VERSION= -DPASLOGOPTIONS=0x02 -DPASLOGAPPZONES=31,23,30,9,8,3 -DNS1_5PORT -DBOARD_TYPE=PRODUCTION     C:/work/PROJ-test/N_Manag/src/nav_event_rcv.cpp -o C:/work/PROJ-test/N_Manag/src/bld/N_Manag//armle-v7/release/nav_event_rcv.cpp.o</code></p>
  
  <p>When I run this command twice in a row, the two <code>.obj</code> files are different and not just a few bytes from a timestamp.</p>
  
  <p>We're switching build systems so we want our builds to be binary compatible. The vast majority of my object files are binary identical. A few that use the <code>__DATE__</code> and <code>__TIME__</code> macros are different by a few bytes but this one is wildly different!</p>
  
  <p>I used an elf-dump utility and found the section that is wildly different between two compiles is this</p>
  
  <pre><code>  [544] .debug_info
         PROGBITS        00000000 047d70 1021ed 00   0   0  1
         [00000000]: 
  </code></pre>
  
  <p>But I don't know what <code>PROGBITS</code> contains and why it contains different items for consective compiles. <a href="https://www.tortall.net/projects/yasm/manual/html/objfmt-elf-section.html" rel="nofollow noreferrer">This site</a> just states that <code>PROGBITS</code> is an attribute but not what it indicates (and why it'd be different for consecutive compiles).</p>
  
  <p><strong>QUESTION</strong></p>
  
  <p>How do I make the generation of the <code>.obj</code> binary deterministic ?</p>
  
  <p><strong>THOUGHTS</strong></p>
  
  <p>Somehow, the code being compiled is actually modifying the <code>.debug_info</code> section of the <code>.obj</code>. This <code>.cpp</code> uses a bunch of boost libraries; is it possible that's the cause?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I looked at the assembly files being generated and they are different. Makes sense that the resulting <code>.obj</code>s would be different.<br>
  Still doesn't make sense why this is happening.</p>
  
  <p><strong>UPDATE</strong>
  The <code>qcc</code> command above is not the actual compiler command executed: <code>qcc</code> is a compiler "redirector" in that it will call the one that matches the <code>-V</code> argument.
  The "real" compiler call is this:</p>
  
  <p><code>C:/work/Proj/QNX_SDK/host/win32/x86/usr/lib/gcc/arm-unknown-nto-qnx6.5.0eabi/4.4.2/cc1plus -Wall -O3 -ggdb3 -DBUILD_VERSION= -DPASLOGOPTIONS=0x02 -DPASLOGAPPZONES=31,23,30,9,8,3 -DNS1_5PORT -DBOARD_TYPE=PRODUCTION  -quiet -fno-builtin -fpic -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mlittle-endian -nostdinc -nostdinc++ -D__cplusplus -D__QNX__ -D__QNXNTO__ -D__GNUC__=4 -D__GNUC_MINOR__=4 -D__GNUC_PATCHLEVEL__=2 -D__NO_INLINE__ -D__DEPRECATED -D__EXCEPTIONS -D__unix__ -D__unix -D__ELF__ -fpic -DPIC=1 -D__ARM__ -D__arm__ -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -D__LITTLEENDIAN__ -D__ARMEL__ -U__ARMEB__ -frandom-seed=sadfsasafssadsa -MP -MT C:/work/Proj/N_Manag/src/bld/N_Manag//armle-v7/release/nav_event_rcv.cpp.o -MMD C:/work/Proj/N_Manag/src/bld/N_Manag//armle-v7/release/nav_event_rcv.cpp.d -isystem C:/work/Proj/QNX_SDK/target/qnx6/usr/include -isystem C:/work/Proj/QNX_SDK/host/win32/x86/usr/lib/gcc/arm-unknown-nto-qnx6.5.0eabi/4.4.2/include -isystem C:/work/Proj/QNX_SDK/target/qnx6/usr/include/cpp/c -isystem C:/work/Proj/QNX_SDK/target/qnx6/usr/include/cpp C:/work/Proj/N_Manag/src/nav_event_rcv.cpp -dumpbase C:/work/Proj/N_Manag/src/nav_event_rcv.cpp -o C:\work\Proj\nav_event_rcv.s</code></p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I think it'd be worthwhile to look at the <code>.s</code> assembly output since there are major differences there.</p>
  
  <p>Remember, I'm using <code>-frandom-seed</code>.</p>
  
  <p>The <code>.s</code> file is 1.05mil lines and it's at line ~900k that the differences start.</p>
  
  <p>Left:  </p>
  
  <blockquote>
    <p>.LASF17345:<br>
    .ascii    "_ZN5boost6detail7variant21make_initializer_node5app"<br>
    .ascii    "lyINS_3mpl4pairINS3_INS5_INS3_INS5_INS3_INS5_INS3_I"<br>
    .ascii    "NS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_IN"<br>
    .ascii    "S5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS"<br>
    .ascii    "5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS1_16in"<br>
    .ascii    "itializer_rootEN4mpl_4int_ILi0EEEEENS4_6l_iterINS4_"<br>
    ...</p>
  </blockquote>
  
  <p>Right:  </p>
  
  <blockquote>
    <p>.LASF17764:<br>
    .ascii  "_ZNKSt8numpunctIcE13decimal_pointEv\000"<br>
    .LASF10304:<br>
    .ascii    "cAlpha0\000"<br>
    .LASF10222:<br>
    .ascii    "usWeek\000"<br>
    .LASF14117:<br>
    .ascii    "_ZN5boost10shared_ptrI27TnRespTravelEstimationEvent"<br>
    .ascii    "EaSERKS2_\000"<br>
    ...</p>
  </blockquote>
  
  <p>It goes on for several hundred bytes.</p>
  
  <p>Now that I examine my beyond compare closely, all the difference sections are due to <code>boost::detail::variant::make_initializer_node</code>. Does that boost function generate different code each time?</p>
  
  <p><strong>RESOLUTION</strong></p>
  
  <p>Turns out it's a <code>gcc</code> bug. I compiled my <code>.cpp</code> with all permutations of <code>-O&lt;X&gt; -ggdb&lt;Y&gt;</code> and for Y>=2, the assembly files <code>.s</code> and the objects <code>.obj</code> are non-deterministic.</p>
  
  <p>I found <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65015" rel="nofollow noreferrer">a gcc bug</a> that describes this issue.</p>
  
  <hr>
  
  <p>I had to delete the other post for . . . reasons.</p>