먼저, 내가 하려는 작업에 대한 간단한 설명은 다음과 같습니다.

먼저, 내가 하려는 작업에 대한 간단한 설명은 다음과 같습니다.

나는 snipersim이 매우 일반적인 "프로젝트"가 아니라는 것을 알고 있지만 이것은 다른 무엇보다 Linux/링크 문제에 더 가깝기 때문에 여기에 남아 있다고 가정합니다. 개발자에게도 연락했지만 아직 답변을 받지 못했습니다.

먼저, 내가 하려는 작업에 대한 간단한 설명은 다음과 같습니다.

석사 논문에서는 건설 시뮬레이터 저격수(snipersim)를 사용했습니다.http://www.snipersim.org). 내 로컬 컴퓨터(Linux Mint 17.2 실행)에 다운로드하여 빌드하고 사용하기 시작했습니다. 모든 것이 잘 작동합니다.

각각 몇 시간이 걸리는 수백 개의 시뮬레이션을 실행해야 했기 때문에 x86_64 OpenSUSE 13.1 시스템에서 HTCondor를 사용하여 대학 컴퓨팅 클러스터에 액세스할 수 있었습니다. 분명히 클러스터에 대한 루트 액세스 권한이 없습니다.

배포판이 다르기 때문에 단순히 바이너리를 복사할 수 없으므로(나중에 시도했지만 코드가 비정상적으로 작동함) snipersim을 다시 컴파일하고 싶습니다.

나의 편집 과정

condor_submit을 사용하여 병렬 작업을 제출할 수 있는 클러스터의 액세스 머신에서 snipersim 포크를 복제했습니다.

SQLite3

필요한 라이브러리가 설치되어 있는지 확인했는데 libsqlite3이 누락된 것으로 나타났습니다. 이 문제를 해결하기 위해 SQLite.org 웹사이트에서 sqlite-autoconf-3090200.tar.gz를 다운로드하고 ~/sqlite(./configure -prefix=~/sqlite)에 설치하도록 구성한 후 make && make install.

그런 다음 , 및 둘 다를 가리키 도록 SQLITE_PATH구성 했습니다 .~/sqliteLIBRARY_PATHLD_LIBRARY_PATH~/sqlite/lib

여태까지는 그런대로 잘됐다.

(향후 참고를 위해 예, SQLite3은 -fPIC로 컴파일됩니다)

저격병

모든 라이브러리를 완성한 후 스나이퍼 컴파일을 시작했습니다. 홈 디렉토리로 전환하고 를 입력합니다 make. 내 홈 컴퓨터에서와 마찬가지로 모든 것이 괜찮아 보입니다. 주요 실행 파일을 연결하는 최종 단계에 도달하기 전에 모든 종속성, 소스 파일 등을 거칩니다 sniper. 여기서 갑자기 오류가 발생하고 중지됩니다.

[LD    ] lib/sniper
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/../../../../x86_64-pc-linux-gnu/bin/ld: ~/sniper/standalone/../standalone/standalone.o: relocation R_X86_6ldrelocationssnipecompilation4_32S against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
~/sniper/standalone/../standalone/standalone.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:34: recipe for target '~/sniper/standalone/../lib/sniper' failed
make: *** [~/sniper/standalone/../lib/sniper] Error 1

이 오류 메시지는 나를 당황하게 만들었습니다. 모든 것이 -fPIC으로 컴파일되므로 오류는 외부에서 가져온 일부 라이브러리와 관련이 있어야 합니다.

여기에서 연결을 위해 실행한 명령(스나이퍼를 사용해본 적이 없는 분들을 위해)(실제로는 "~"가 아닌 전체 경로를 사용하지만, 개인 식별 정보가 많이 포함되어 있으므로 "~"로 대체했습니다):

g++ -L~/sniper/standalone/../lib -L~/sniper/standalone/../sift -L~/sniper/standalone/../pin_kit/extras/xed-intel64/lib -L~/sqlite/lib -L~/sniper/standalone/../pin_kit/extras/xed2-intel64/lib -o ~/sniper/standalone/../lib/sniper ~/sniper/standalone/../standalone/exceptions.o ~/sniper/standalone/../standalone/standalone.o -lcarbon_sim -lpthread -lsift -lxed -L~/sniper/standalone/../python_kit/intel64/lib -lpython2.7 -lrt -lz -lsqlite3 -lxed -O2 -g -std=c++0x

특히 -lcarbon_sim -sift이 프로세스의 앞부분에서 컴파일된 사용자 정의 라이브러리를 참조 make하고 -lxedIntel PIN 라이브러리(프로세서 감지에 사용됨)를 참조하십시오.

내 생각/내가 시도한 것

이는 놀라운 오류 메시지입니다. 어떤 이유로 Standalone.o는 위치 의존적이며 공유 객체로 컴파일될 수 없다고 명시되어 있습니다.모두컴파일 단계에는 -fPIC(3중 확인)이 있습니다. 다시 한 번 생각나는 것은 끌어들이는 라이브러리 중 하나가 -fPIC 없이 컴파일되었다는 것입니다. 그럴 가능성은 낮으며 뭔가 간과하고 있는 것이 분명합니다. ld가 가져오는 모든 라이브러리 목록을 인쇄하도록 하는 방법이 있습니까? 예를 들어, 문제를 파악할 수 있다면 수동으로 컴파일된 라이브러리를 가져올 수도 있습니다.

또한 내 집 컴퓨터에서 재배치를 확인했는데 ld가 ( R_X86_64_32S against .rodata.str1.1)에 대해 불평하는 독립형.o 파일에 똑같은 재배치가 존재하지만 모든 것이 잘 작동합니다.

나는 이것이 SQLite3의 사용자 정의 설치 때문일 것이라고 생각하여(집 컴퓨터의 패키지 관리자를 통해 설치했습니다) 클러스터에서와 똑같은 프로세스를 통해 집 컴퓨터에 복사본을 설치해 보았습니다. 모든 것이 여전히 작동하며 ldd를 통해 실제로 내 복사본(시스템 버전 아님)에 연결되어 있음을 확인했습니다.

또한 두 시스템 간의 gcc, g++ 및 ld 버전을 비교했는데 일치했습니다.

또한 이상한 점을 발견했습니다. 파일 ~/sniper/lib/pin_sim.so(인텔 PIN 라이브러리를 가져오는 일부 저격 코드에서 컴파일됨)은 64비트 동적으로 링크된 ELF 실행 파일(예상대로)이지만 내 집 컴퓨터에서 실행하면 인쇄하면 ldd pin_sim.so모두 not a dynamic executable인쇄됩니다. 사용되는 공유 라이브러리. pin_sim.so내 컴퓨터에서 클러스터로 복사를 시도했지만 ldd도 이를 읽을 수 없습니다. readelf -d pin_sim.so여전히 두 컴퓨터 모두에서 작동합니다.

이것은 매우 이상합니다. readelf/objdump 없이 ldd가 실패하는 것에 대해 내가 찾을 수 있는 유일한 참조는 64비트 시스템의 32비트 실행 파일에서 호출할 때입니다. 이 경우 실행 파일과 시스템이 모두 64비트이므로 그렇지 않습니다.


나는 무엇을 해야할지 전혀 모른다. 비슷한 문제에 대한 해결책을 찾기 위해 오늘 약 5시간 동안 웹을 검색했지만 성공하지 못했습니다. 여기 누군가 아이디어가 있기를 바랍니다.


편집 1: 두 시스템 간의 링커 매개변수 비교

-vsblingx가 제안한 대로 링커(collect2) 호출 시 차이점을 찾기 위해 인수를 사용하여 두 시스템 모두에서 g++를 실행했습니다 . 나는 그것들을 약간 정리하고(전체 경로가 아닌 관련 파일 이름만) 라이브러리 디렉토리를 제거했습니다(-L):

일반적으로 사용되는 매개변수:

--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o lib/sniper
crti.o crtn.o
standalone/exceptions.o standalone/standalone.o
-lcarbon_sim -lpthread -lsift -lxed -lpython2.7 -lrt -lz -lsqlite3 -lxed -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc 

내 집 컴퓨터에 특정한 매개변수(스나이퍼가 작동하는 Linux Mint 17.2):

--sysroot=/ --build-id -z relro
crt1.o crtbegin.o crtend.o

클러스터 시스템 관련 매개변수(효과가 없는 경우):

-pie -z now
Scrt1.o crtbeginS.o crtendS.o

연결에 대해 잘 모르지만 내 집 설정에는 이 포함되어 crt1.o crtbegin.o crtend.o있고 클러스터에는 포함되어 있다는 것을 알았습니다 Scrt1.o crtbeginS.o crtendS.o(추가 "S" 참고). 이 파일들이 정확히 어떤 역할을 하는지, 그리고에스파일 이름은 무엇을 의미합니까? (내 생각에는 "공유" 또는 "정적" 중 하나인 것 같습니다.)

답변1

이유

"-pie" 매개변수가 Sniper 컴파일을 중단시키는 것 같습니다. 내 집 컴퓨터에 추가하려고 했지만 똑같은 오류로 인해 실패했습니다. 클러스터 라인에서 이를 제거하면 링커가 성공합니다.

사용자 silynx가 언급했듯이 OpenSUSE(적어도 클러스터에 있는 것)는 연결 시 실행 파일이 PIE를 사용하도록 강제하는 반면 Linux Mint는 그렇지 않습니다.


해결책

COLLECT_GCC_OPTIONS를 재정의하기 위해 -fno-pie파일에 $(TARGET) 링커 호출을 추가하면 모든 것이 잘 작동하는 것 같습니다.standalone/Makefile-pie

ldd pin_sim.so여전히 작동하지 않지만 이는 완전히 또 다른 문제입니다. 사실 이에 대해서는 별도의 질문을 게시할 수도 있습니다.

관련 정보