2013-02-27 3 views
5

Выводит ли файл gcc объектного файла (язык C) между компиляциями? Нет никакой информации о времени, никаких изменений в параметрах компиляции или исходном коде. Никаких изменений в связанных библиотеках и переменных окружения. Это кросс-компилятор VxWorks MIPS64, если это помогает. Я лично считаю, что это не должно меняться. Но я наблюдаю, что иногда случайным образом, инструкции порождали изменения. Я не знаю, в чем причина. Может ли кто-нибудь пролить свет на это?Могут ли файлы объектов, выводимые gcc, варьироваться между компиляциями одного и того же источника с одинаковыми параметрами?

+0

Просьба уточнить: каждый раз ваш исходный код остается неизменным? Изменились ли другие связанные библиотеки? Входит ли информация о времени в источник (например, время сборки или ревизия VCS #)? Не могли бы вы привести пример, который может воспроизвести проблему? –

+0

Вы уверены, что изменения действительно действительны? Возможно, что в каком-то разделе содержатся неинициализированные биты, возможно, потому, что GCC «знает» эти биты не имеет значения. Состояние неинициализированных битов может, разумеется, варьироваться случайным образом между прогонами одной и той же программы на одном и том же входе. – unwind

+0

@MichaelFoukarakis: Нет, никаких временных меток в коде. Библиотеки остаются прежними. Уже упоминалось в заголовке, что источник не изменяется. –

ответ

0

Почему это должно отличаться? Это тот же результат всегда. Попробуйте следующее:

for i in `seq 1000`; do gcc 1.c; md5sum a.out; done | sort | uniq | wc -l 

Ответ всегда 1. Замените 1.c и a.out в соответствии с вашими потребностями.

Приведенное количество подсчитывает, сколько разных исполняемых файлов генерируется gcc при компиляции того же источника для 1000 раз.

+0

Попробуй что? Не могли бы вы рассказать? –

+0

Извините, отправил его слишком рано :( –

+0

ОК, я пробовал такие вещи. Наша гипотеза о том, что она не должна меняться, по-видимому, верна. Но для кода большого размера делает то же самое верно. Может ли компилятор сгенерировать один набор инструкций в компиляции 'c1', а затем сгенерировать другой вывод для компиляции 'c2', но сохраняя функциональность такой же? –

1

Как это построено? Например, если я построил одно и то же ядро ​​Linux, он включает в себя счетчик, который увеличивает каждую сборку. GCC имеет опции для использования информации профилировщика для руководства генерации кода, если информация профилирования изменяется, так же как и код.

Что вы анализировали? Сгенерированная сборка, objdump объектных файлов или исполняемый файл? Как вы сравнили разные версии? Вы уверены, что вы смотрели на исполняемый код, а не на метки компилятора/ассемблера/компоновщика?

Что-то изменилось в окружающей среде? Новые библиотеки (и файлы заголовков/декларации/определения макросов!)? Новый компилятор, компоновщик? Новое ядро ​​(да, некоторые файлы заголовков берутся с исходным кодом ядра и поставляются вместе с ним)?

Любые изменения в переменных среды (другой пользователь, выполняющий компиляцию, другую машину, различные подключения к сети, дает другой IP-адрес, который делает его способом в сборке)?

Я бы попытался подробно отслеживать процесс сборки (запустите сборку и запишите вывод в файл и сделайте это снова, сравните их).

Полностью озадачен ...

+0

«Как это построено? Например, если я построил одно и то же ядро ​​Linux, он включает в себя счетчик, который увеличивает каждую сборку. GCC имеет опции для использования информации о профилировщике для руководства генерации кода, если информация профилирования изменяется, код." -> Нет информации о профиле/отлаживании; -O2 включен. –

+0

«Что вы анализировали?» -> генерирует objdump и сравнивается. Разница заключалась в машинных инструкциях в функции. Я только компилирую статическую библиотеку, поэтому никакой исполняемый файл ... Я не анализировал статическую библиотеку. Я бы проигнорировал временные метки, если бы это было так. Разница была явно машинной инструкцией. Никаких изменений окружающей среды. В моем случае использования немыслимо менять ядра между двумя компиляциями. Такой потребности нет. Я создаю библиотеку для встроенной системы через кросс-компилятор. Я также попытался сравнить журнал построения. Нет никакой разницы. –

+0

@arun, были ли эти отличия? Очень, очень странно. – vonbrand

1

У меня была аналогичная проблема с г ++. В версиях Pre 4.3 каждый раз создавались точно такие же объектные файлы. С 4.3 (и позже?) Некоторые из искаженных имен символов различны для каждого прогона - даже без -g или других записей. Возможно, используйте временную метку или случайное число (надеюсь, нет). Очевидно, некоторые из этих символов попадают в таблицу символов .o, и вы получаете разницу. Зачистка объектного файла (ов) делает их равными снова (по бинарному сравнению). g ++ -c file.C; strip file.o; cmp file.o origfile.o

-1

Мой gcc иногда производит разный код для точно такого же ввода. Файлы выходных объектов отличаются только одним байтом.

Иногда это вызывает ошибки компоновщика, поскольку один возможный объектный файл недействителен. Повторная компиляция другой версии обычно исправляет ошибку компоновщика.

Версия gcc 4.3.4 на Suse Linux Enterprise. ССАГПЗ Параметры являются:

cc -std=c++0x -Wall -fno-builtin -march=native -g -I<path1> -I<path2> -I<path3> -o obj/file.o -c file.cpp 

Если кто-то испытывает тот же эффект, то пожалуйста, дайте мне знать.

0

Я обнаружил, что по крайней мере в некоторых средах один и тот же источник может выдавать другой исполняемый файл, если исходное дерево для последующей сборки находится в другом каталоге. Пример:

Оформить заказ оригинальной копии вашего проекта на dir1. Сделайте полную перестройку с нуля.

Затем, с тем же пользователем на той же машине, проверьте ту же точную копию исходного кода на dir2 (dir1! = Dir2). Сделайте еще одну полную перестройку с нуля.

Эти сборки находятся в нескольких минутах друг от друга, без изменений в toolchain или каких-либо сторонних libs или кода. Двоичное сравнение исходного кода одинаков. Однако исполняемый файл в dir1 имеет разный md5sum, чем исполняемый файл в dir2.

Если я сравниваю различные исполняемые файлы в шестнадцатеричном редакторе BeyondCompare, разница - это не просто крошечный раздел, который мог бы быть вероятной меткой времени.

Я сделать получить тот же исполняемый файл, если я построю в dir1, а затем восстановить снова в dir1. То же самое, если я продолжаю строить один и тот же источник снова и снова из dir2.

Мое единственное предположение, что в исполняемый файл встроены какие-то абсолютные пути иерархии include.

 Смежные вопросы

  • Нет связанных вопросов^_^