Si compilara un programa en un solo binario, creara una suma de verificación y luego lo volviera a compilar en la misma máquina con la misma configuración del compilador y del compilador y sumara el programa recompilado, ¿fallaría la suma de verificación?
Si es así, ¿por qué es esto? Si no, ¿tener una CPU diferente daría como resultado un binario no idéntico?
Respuestas:
Compile el mismo programa con la misma configuración en la misma máquina:
Aunque la respuesta definitiva es "depende", es razonable esperar que la mayoría de los compiladores sean deterministas la mayor parte del tiempo y que los binarios producidos sean idénticos. De hecho, algunos sistemas de control de versiones dependen de esto. Aún así, siempre hay excepciones; es muy posible que algún compilador en algún lugar decida insertar una marca de tiempo o algo así (iirc, Delphi lo hace, por ejemplo). O el proceso de construcción en sí podría hacer eso; He visto archivos MAKE para programas en C que establecen una macro de preprocesador en la marca de tiempo actual. (Sin embargo, supongo que eso contaría como una configuración de compilador diferente).
Además, tenga en cuenta que si vincula estáticamente el binario, entonces está incorporando efectivamente el estado de todas las bibliotecas relevantes en su máquina, y cualquier cambio en cualquiera de ellas también afectará su binario. Por lo tanto, no son solo las configuraciones del compilador las que son relevantes.
Compile el mismo programa en una máquina diferente con una CPU diferente.
Aquí, todas las apuestas están apagadas. La mayoría de los compiladores modernos son capaces de realizar optimizaciones específicas del objetivo; Si esta opción está habilitada, es probable que los binarios difieran a menos que las CPU sean similares (e incluso entonces, es posible). Además, consulte la nota anterior sobre la vinculación estática: el entorno de configuración va mucho más allá de la configuración del compilador. A menos que tenga un control de configuración muy estricto, es extremadamente probable que algo difiera entre las dos máquinas.
fuente
gcc -c
puede ser idéntica, pero las versiones vinculadas difieren. Además, no es solo-march
; También hay-mtune/-mcpu
y-mfpmatch
(y posiblemente otros). Algunos de estos pueden tener diferentes valores predeterminados en diferentes instalaciones, por lo que es posible que deba forzar explícitamente el peor caso posible para sus máquinas; hacerlo podría reducir significativamente el rendimiento, especialmente si vuelve a i386 sin sse. Y, por supuesto, si uno de sus cpus es un ARM y el otro un i686 ...Lo que está preguntando es "es el resultado determinista ". Si compiló el programa una vez, inmediatamente lo compiló nuevamente, probablemente terminaría con el mismo archivo de salida. Sin embargo, si algo cambió, incluso un pequeño cambio, especialmente en un componente que utiliza el programa compilado, entonces la salida del compilador también podría cambiar.
fuente
-frandom-seed=string
.Para todos los compiladores? No. El compilador de C #, al menos, no está permitido.
Eric Lippert tiene un desglose muy completo sobre por qué la salida del compilador no es determinista .
Aunque es específico de una versión del compilador de C #, muchos puntos del artículo se pueden aplicar a cualquier compilador.
fuente
-frandom-seed=123
controla algo de aleatoriedad interna del CCG.man gcc
dice:__FILE__
: coloca la fuente en una carpeta fija (por ejemplo/tmp/build
)__DATE__
,__TIME__
,__TIMESTAMP__
:-D
-Wdate-time
o-Werror=date-time
: una advertencia o un error si cualquiera de los dos__TIME__
,__DATE__
o__TIMESTAMP__
se está utilizado. El kernel 4.4 de Linux lo usa por defecto.D
bandera conar
, o use https://github.com/nh2/ar-timestamp-wiper/tree/master para limpiar sellos-fno-guess-branch-probability
: las versiones manuales anteriores dicen que es una fuente de no determinismo, pero ya no . No estoy seguro si esto está cubierto-frandom-seed
o no.El proyecto de compilaciones de Debian Reproducible intenta estandarizar los paquetes de Debian byte a byte, y recientemente recibió una subvención de la Fundación Linux . Eso incluye más que solo compilación, pero debería ser de interés.
Buildroot tiene una
BR2_REPRODUCIBLE
opción que puede dar algunas ideas a nivel de paquete, pero está lejos de completarse en este momento.Hilos relacionados:
fuente
El proyecto https://reproducible-builds.org/ tiene que ver con esto, y está tratando de hacer que la respuesta a su pregunta "no, no diferirán" en tantos lugares como sea posible. NixOS y Debian ahora tienen más del 90% de reproducibilidad para sus paquetes.
Si compila un binario, y yo compilo un binario, y son idénticos bit por bit, entonces puedo estar seguro de que el código fuente y las herramientas son los que determinan la salida, y que usted no se escabulló en algunos código troyano en el camino.
Si combinamos la reproducibilidad con bootstrappability de una fuente legible por humanos, como http://bootstrappable.org/ está trabajando en hacerlo, obtenemos un sistema determinado desde cero por una fuente legible por humanos, y solo entonces estamos en un punto donde Podemos confiar en que sabemos lo que está haciendo el sistema.
fuente
Yo diría que NO, no es 100% determinista. Anteriormente trabajé con una versión de GCC que genera binarios de destino para el procesador Hitachi H8.
No es un problema con la marca de tiempo. Incluso si se ignora el problema de la marca de tiempo, la arquitectura específica del procesador puede permitir que la misma instrucción se codifique de 2 maneras ligeramente diferentes donde algunos bits pueden ser 1 o 0. Mi experiencia previa muestra que los binarios generados fueron la misma la MAYORÍA del tiempo pero ocasionalmente el gcc generaría binarios con un tamaño idéntico pero algunos de los bytes son diferentes en solo 1 bit, por ejemplo, 0XE0 se convierte en 0XE1.
fuente
En general, no. Los compiladores más sofisticados incluirán el tiempo de compilación en el módulo objeto. Incluso si tuviera que reiniciar el reloj, tendría que ser muy preciso con respecto a cuándo inició la compilación (y luego esperar que los accesos al disco, etc., tengan la misma velocidad que antes).
fuente