Вывод файла GCC .obj не является детерминированным (.debug_info, раздел PROGBITS)

Моя команда компиляции
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

Когда я запускаю эту команду дважды подряд, два .obj файлы отличаются, а не только несколько байтов от отметки времени.

Мы переключаем системы сборки, поэтому мы хотим, чтобы наши сборки были двоично-совместимыми. Подавляющее большинство моих объектных файлов являются двоичными идентичными. Некоторые, которые используют __DATE__ а также __TIME__ Макросы отличаются на несколько байтов, но этот дико отличается!

Я использовал утилиту elf-dump и обнаружил, что раздел между двумя компиляциями сильно отличается

  [544] .debug_info
PROGBITS        00000000 047d70 1021ed 00   0   0  1
[00000000]:

Но я не знаю что PROGBITS содержит и почему он содержит различные элементы для последовательных компиляций. Этот сайт просто утверждает, что PROGBITS это атрибут, но не то, что он указывает (и почему он будет другим для последовательных компиляций).

ВОПРОС

Как мне сделать поколение .obj бинарный детерминированный?

МЫСЛИ

Каким-то образом компилируемый код фактически изменяет .debug_info раздел .obj, это .cpp использует кучу буст-библиотек; возможно ли это причина?

ОБНОВИТЬ

Я посмотрел на генерируемые файлы сборки, и они разные. Имеет смысл, что в результате .objс будет иначе.
Все еще не имеет смысла, почему это происходит.

ОБНОВИТЬ
qcc Команда выше не является действительной командой компилятора: qcc компилятор «перенаправитель» в том, что он будет вызывать тот, который соответствует -V аргумент.
«Настоящий» вызов компилятора таков:

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

ОБНОВИТЬ

Я думаю, что стоит взглянуть на .s сборочный вывод, так как там есть большие различия.

Помни, я использую -frandom-seed,

.s файл имеет размер 1,05 миллиона строк, и разница составляет около 900 тысяч.

Оставил:

.LASF17345:
.ascii «_ZN5boost6detail7variant21make_initializer_node5app»
.ascii «lyINS_3mpl4pairINS3_INS5_INS3_INS5_INS3_INS5_INS3_I»
.ascii «NS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_IN»
.ascii «S5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS»
.ascii «5_INS3_INS5_INS3_INS5_INS3_INS5_INS3_INS5_INS1_16in»
.ascii «itializer_rootEN4mpl_4int_ILi0EEEEENS4_6l_iterINS4_»

Правильно:

.LASF17764:
.ascii «_ZNKSt8numpunctIcE13decimal_pointEv \ 000»
.LASF10304:
.ascii «cAlpha0 \ 000»
.LASF10222:
.ascii «usWeek \ 000»
.LASF14117:
.ascii «_ZN5boost10shared_ptrI27TnRespTravelEsificationEvent»
.ascii «EaSERKS2_ \ 000»

Это продолжается в течение нескольких сотен байтов.

Теперь, когда я тщательно проверяю свое невообразимое сравнение, все разделы различий boost::detail::variant::make_initializer_node, Эта функция повышения каждый раз генерирует другой код?

РАЗРЕШАЮЩАЯ СПОСОБНОСТЬ

Оказывается, это gcc ошибка. Я собрал свой .cpp со всеми перестановками -O<X> -ggdb<Y> а для Y> = 2 файлы сборки .s и объекты .obj являются недетерминированными.

я нашел ошибка gcc который описывает эту проблему.


Мне пришлось удалить другой пост для. , , причины.

5

Решение

Причины недетерминизма

Обычные виновники — макросы __DATE__, __TIME__, __TIMESTAMP__ который компилятор расширяет до значений, рассчитанных по системному времени.

Одна возможность состоит в том, что отладочная информация, сгенерированная для двоичного файла, написана недетерминированным способом. Это может произойти, например, когда расположение в памяти отладочной информации в процессе компиляции не является детерминированным. Я не знаю внутренностей GCC. Но я думаю, что-то подобное может произойти, когда

Последний источник недетерминизма обычно считается ошибкой в ​​компиляторе (например, GCC PR65015)

смягчение

Для принудительного воспроизведения воспроизводимых расширений __DATE__, __TIME__ а также __TIMESTAMP__ макросами, нужно эмулировать и подделывать системное время (например, используя libfaketime / faketime) к компилятору. -Wdate-time Опция командной строки для GCC может использоваться для предупреждения всякий раз, когда используются эти предопределенные макросы.

Чтобы вызвать воспроизводимую «случайность» для GUID и искажения, вы можете попробовать скомпилировать -frandom-seed=<somestring> где <somestring> является уникальной строкой для вашей сборки (например, это должен делать хеш содержимого исходного файла, который вы компилируете).

В качестве альтернативы вы можете попытаться скомпилировать без отладочной информации (например, без -ggdb и т. д.) или используйте какой-либо инструмент для удаления полос, чтобы позже удалить раздел с информацией об отладке.

Смотрите также

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]