2014-06-10 2 views
5

긴 디버깅 시퀀스 후에 내 문제가 하나의 파일로 좁혀졌습니다. 그리고 문제는 파일이 두 개의 다른 디렉토리에서 다르게 컴파일된다는 점입니다. 다른 모든 디렉토리는 동일합니다.같은 소스 코드를 컴파일하면 다른 오브젝트 파일을 어떻게 생성 할 수 있습니까?

간단한 파일을 컴파일하기 위해 CodeSourcery의 arm gcc 컴파일러 (gcc 버전 4.3.3, Sourcery G ++ Lite 2009q1-161)를 사용하고 있습니다. 한 모듈에서 문제없이 사용하고 다른 모듈에 복사하여 사용했습니다. 컴파일 할 때 오브젝트 파일은 상당히 다릅니다. 두 파일을 컴파일하는 커맨드 라인은 동일합니다 (나는 리눅스 히스토리를 사용했습니다). 그리고 3 개의 include 파일도 동일한 복사본입니다 (diff로 체크).

2 개의 오브젝트 파일에 대해 2 진 비교를했는데 주변에 여러 개의 개별 바이트 차이가있었습니다. 나는 objdump -D 두 가지를 모두 수행하여 비교했으며 많은 차이가있었습니다. 여기에 dump1, dump2diff이 있습니다. 명령 줄은 " arm-none-eabi-gcc --std = gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o"입니다.

어떻게 가능합니까? 또한 -c 대신 -S로 컴파일하고 어셈블러 출력을 살펴본 결과 디렉토리 경로를 제외하고는 동일합니다. 그렇다면 오브젝트 파일은 어떻게 달라질 수 있습니까?

내 실제 문제는 내 프로그램에 dump2에 대한 개체 파일을 연결하려고하면 정의되지 않은 참조 오류가 발생하므로 개체의 내용이 잘못되었다는 것입니다. 반면 dump1의 개체는 오류가없고 링크가 잘됩니다.

+0

분명히 태그 [tag : binary-reproducibility]가 있습니다. 이 컴파일러에서 같은 것을 보았습니다. * diff *의 대부분은 다른 레지스터 선택이나 파일 오프셋을 보여 주지만 기본적인 기능은 동일합니다. See : [Debian reproducible builds] (https://wiki.debian.org/ReproducibleBuilds). 물론 출력이 다를 수도 있습니다. 너 문제 야? 나는 당신의 문제가 다른 것이라고 생각합니다. –

+0

또한 [각 빌드에서 바이너리가 변경됨] (http://stackoverflow.com/questions/4140329/binary-object-file-changing-in-each-build) 등 –

+0

'-O0 차이가 지속되는지 확인하십시오. – markgz

답변

0

파일이 다른 포함 파일을 선택합니다. 이것이 가장 가능성있는 이유입니다.

include 경로가 include 문과 완전히 동일한지 확인하십시오. 그들은 다른 디렉토리를 가리킬 수 있습니다. C 및 C++에는 #include abcd.h이 호출 파일의 디렉토리에서 abcd.h을로드하려고 할 때 사용하는 기능이 있습니다. 이것을 확인하십시오.

1

대규모 소프트웨어의 경우 많은 구현이 포인터에 해싱을 수행하고 있습니다. 이것은 원인 결과 임의 화의 주요 원인 중 하나입니다. 일반적으로 프로그램 논리가 올바르다면 대부분의 경우 해를 끼치 지 않는 일부 내부 데이터 구조의 순서가 달라질 수 있습니다.

또한 'objdump -D'출력을 비교하지 마십시오. 다른 디렉토리의 코드를 컴파일 중이므로 문자열 테이블, 기호 테이블, DWARF 또는 eh_frame이 달라야합니다. 확실히 많은 diff 행을 얻을 것입니다.

텍스트 섹션 만 처리하는 'objdump -d'의 출력을 비교하는 것이 좋습니다. 텍스트 섹션이 같으면 (유사) 동일한 것으로 간주 될 수 있습니다.

관련 문제