2012-03-14 2 views
2

특정 프로젝트에서 버전 정보를 공유 객체 파일에 포함하려고합니다. 우리는 표준 리눅스 도구를 사용하여 공유 객체를 구문 분석하여 자동화 된 테스트 버전을 결정할 수 있기를 원합니다. 현재 "const int plugin_version = 14;"있습니다. 나는 '나노'와 'objdump를'을 사용하고 있다는 걸 확인할 수 있습니다커맨드 라인에서 글로벌 변수 값 검색

00000000000dcfbc r plugin_version 

나는, 그러나, 명령 줄에서 쉽게 그 변수의 값을 얻을 수있을 수없는 것. 전역 변수에 대한 초기화 된 값을 표시하는 POSIX 도구가 있다고 생각했습니다. 필자는 변수의 형식을 정보 자체 (예 : plugin_version_14)로 사용할 것을 고려해 왔지만 이는 거대한 해킹처럼 보입니다. 파일 이름에 정보를 임베드하는 것은 불행히도 옵션이 아닙니다. 다른 제안은 환영합니다. "MAGIC의 4.56 END 매직 마커 문자열 버전"그럼 그냥 파일의 "매직 STRING"을 찾아서 그 뒤에 오는 버전 정보를 추출

답변

0

끔찍한 해킹 변수 이름의 버전 정보를 포함하는, 그래서 나노 미터가 표시됩니다 :

00000000000dcfbc r plugin_version_14 
+0

이것이 결국 우리의 솔루션이되었습니다. – QBasicer

2

당신은 문자열

로 포함 할 수있다.

표준으로 만들면 모든 소프트웨어에서 이러한 포함 된 문자열을 쉽게 찾을 수 있습니다.

int가 필요하면 작은 매크로 매직이 int와 magic 문자열을 모두 만들어 동기화되지 않는지 확인합니다. 내가 과거에 사용했던

+0

위의 사람들은 문자열을 찾는 파일을 파기하지 않기로 결정했습니다. 나는 실제로 XML을 사용하는 것을 고려했다. – QBasicer

1

내가 생각하는 몇 가지 옵션이있다.

첫 번째 본능은 버전 정보가 ELF 파일의 자체 섹션에 있는지 확인하는 것입니다. objdump -s -j 섹션의 이름은/bin/뭐든 사용할 수 있습니다. 이것은 objdump가 물론 사용 가능하다는 것에 의존합니다.

키스가 제안한 것을 할 수도 있고, 마법의 마커 문자열과 함께 '문자열'을 사용할 수도 있습니다. 이것은 약간 hackish 느낀다, 그러나 확실히 잘 작동해야한다.

마지막으로 왜 --version 명령 줄 옵션을 추가하지 않으시겠습니까? 그런 다음 원하는 버전 정보를 저장하고 소프트웨어가있는 모든 시스템에 설치할 수있는 특정 도구를 사용하여 쉽게 검색 할 수 있습니다.

+0

실제로 플러그인이므로 공유 객체 파일이며 스크립트에서로드 할 실행 파일을 결정하려고 시도합니다. – QBasicer

+0

실행 가능한 공유 라이브러리를 얻기 위해 일부 링커의 속임수를 사용하는 것이 가능할 수도 있습니다. –

0

C/C++에서 해당 버전을 구할 수있는 도구를 직접 작성하지 않으시겠습니까? dlopen, dlsym을 사용하여 기호를 가져 와서 그 값을 표준 출력으로 인쇄 할 수 있습니다. 이 방법으로 기호가 이미 있는지 확인할 수도 있습니다. 그것은 내게 20 ~ 30 줄의 코드와 20 분 정도되는 것처럼 보입니다 :)

나는이 질문이 커맨드 라인에 관한 것이라는 것을 알고 있지만, 그러한 툴을 직접 작성하는 것은 쉽습니다 (특히 그러한 커맨드 라인 도구가 존재하지 않습니다).

+0

나는 이것을 제안했었다. 실제로 그것은 나의 첫 번째 선택 이었지만, 그들은 또 다른 도구를 지원할 필요가 없다. – QBasicer

0

바이너리가 제거되지 않으면 gdb를 사용하여 변수를 인쇄 할 수 있습니다. (나는 방금 gdb를 스크립트하려고 시도했지만, stdin이 tty가 아닌 경우 작업을 거부하는 것으로 보입니다. 아마도 작업을 수행 할 것으로 기대합니까?당신은 파이썬을 사용하여 수용 할 수있는 경우)

0

이 도움이 될 수 있습니다

import struct 
import sys 
import subprocess 

if __name__ == '__main__': 
    so = sys.argv[1] 
    sym = sys.argv[2] 

    addr = subprocess.check_output('nm %s | grep %s' % (so, sym), shell=True) 
    addr = int(addr.split()[0], 16) 

    so_file = open(so) 
    so_file.seek(addr) 
    data = so_file.read(4) 

    print struct.unpack('@i', data)[0] 

면책 조항 :이 스크립트는 (점검 오류를하지 않습니다 당신은 내가 당신이 어떤 가지고 올 수 확신을 좋아하는 경우에;)). 또한 4 바이트 기본 int 값을 읽는 것으로 가정합니다.

$ cat global.c 
const int plugin_version = 14; 
$ python readsym.py global.so plugin_version 
14 
+0

불행히도, 우리는 기계에서 사용할 수있는 파이썬을 기대할 수 없습니다. – QBasicer

관련 문제