2017-12-07 16 views
-2

우리는 실행 파일을 만들기 위해 함께 컴파일 된 모든 파일을 쉽게 나열 할 수있는 절차를 찾고 있습니다.실행 파일을 만들기 위해 함께 컴파일되는 모든 파일에 대해 알아야하는 방법은 무엇입니까?

사용 케이스 :

dwarfdump a.out | grep "NS uri" 
0x0000064a [ 9, 0] NS uri: "/home/main.c" 
0x000006dd [ 2, 0] NS uri: "/home/zzzz.c" 
0x000006f1 [ 2, 0] NS uri: "/home/yyyy.c" 
0x00000705 [ 2, 0] NS uri: "/home/xxxx.c" 
0x00000719 [ 2, 0] NS uri: "/home/wwww.c" 
: 우리는 큰 저장소를 가지고 우리가 실행 파일을 만들기 위해 컴파일 된 저장소에 존재하는 파일 예를 들어 (즉, a.out의)

이 무엇인지 모두 알고 싶어, 가정

하지만 모든 헤더 파일은 나열되지 않습니다. 를 제안하십시오.

+1

는 왜 물어 않으며, 사용 사례는 무엇인가?** 질문을 수정하여 ** 개선하고 동기를 부여하고 더 많은 컨텍스트를 제공하십시오. –

+0

편집을하더라도 파일 경로 만 필요하면 이해할 수 없습니다. 편집 한 질문에서 * location *의 의미는 무엇입니까? –

+0

그러나 귀하의 질문은 DWARF에 대한 지식 부족을 보여줍니다. 더 자세하게 그 형식을 공부하십시오 –

답변

3

디버그 기호로 실행 파일에서 소스 코드를 추출하는 방법 사용할 수 있습니까?

할 수 없습니다. 나는 당신이 Linux/x86-64에 있다고 생각한다. (그리고 당신의 질문은 operating systemABI과 특정 디버깅 형식이다.) 물론 실행 파일에 대한 gcc 컴파일 명령 모두에 pass-g (또는 even-g3)을 사용해야합니다. 그게 아니면 -g 또는 -g3 옵션을 사용하여 을 컴파일 할 때마다translation unit (아마도 공유 라이브러리를 포함하여!) 정보가 충분하지 않을 수 있습니다. 심지어 DWARF 형식 debug information

ELF 실행 파일은 소스 코드를 포함하지 않지만 (행과 열 번호와 같은 예를 들어, 소스 파일 경로, 위치) 소스 코드 만 참조. 따라서 디버그 정보에는 파일 src/foo.c, 줄 34 열 5와 같은 내용이 포함되어 있습니다 (단, 내용의src/foo.c에 해당하지 않음). 물론 gdb은 파일 경로 src/foo.c을 알고 있으므로 해당 소스 파일 (사용 가능한 경우 최신 w.r.t. 실행 파일)을 읽을 수 있으므로이를 나열 할 수 있습니다.

디버깅 메타 데이터 추출은 다른 질문입니다. DWARF를 이해하면 objdump 또는 readelf 또는 addr2line 또는 dwarfdump or libdwarf과 같은 도구를 사용할 수 있습니다. gdb (최근 버전의 GDB는 Python이나 Guile에서 extendable이 될 수 있습니다)을 ELF 실행 파일에 사용할 수 있습니다.

아마 Ian Taylor의 libbacktrace을 고려해야합니다. DWARF 정보를 사용하여 런타임에 멋진 백 트레이스를 제공합니다.

BTW, cgdb 정보를 처리 드워프 모든 실제 작업을 수행 (ddd 등)만을 전단gdb이다. free software이면 소스 코드를 연구 할 수 있습니다.

내가에만 a.out는 당신이 dwarfdump -i | grep DW_AT_decl_file을 시도 할 수 있습니다 할 파일 이름

을 나열 할 당신은 grep 대신 일부 GNU awk 명령을 사용할 수 있습니다.당신은 details of DWARF specifications에 뛰어 필요가 있고 당신은 elf(5) 형식에 대한 자세한 내용을 이해할 필요가있다.

는 그것은 모든 헤더 파일이 예상되는

아래로 나열되지 않습니다. 대부분의 헤더 파일은 코드선언을 포함하지 않는 (예 : printfmusl-libc 사용하는 경우 <stdio.h>뿐만 tree/src/stdio/printf.c의 예를 들어 당신의 C standard library의 일부 C 소스 파일에을 구현되지 되어 그냥 을 선언하다 in /usr/include/stdio.h). DWARF (및 기타 디버그 정보 형식)는 binary code을 설명합니다. 일부 헤더 파일은 일부 사전 처리기 매크로 (사전 처리 시간에 확장되거나 건너 뛴다)에 대한 액세스 권한을 부여하기 위해서만 포함됩니다.

어쩌면 homoiconic 프로그래밍 언어를 꿈꿔 본 다음 Common Lisp을 시도해보십시오 (예 : SBCL). 귀하의 질문에 gdb를 사용하는 방법을 경우

, 다음 Debugging with GDB 매뉴얼을 참조하십시오.

질문이 decompilers 인 경우 일반적으로 불가능한 작업 임 (예 : Rice's theorem). BTW, 대부분의 리눅스 배포판 내부 프로그램은 일반적으로 free software이있다, 그래서 소스 코드를 얻을 아주 쉽게 (그리고 당신도 리눅스에 독점 소프트웨어를 사용하여 피할 수).

BTW, 당신은 또한 gccmore flags를 전달하여 컴파일 시간에 더 많은 일을 할 수 있습니다. 당신은 수도 pass-H 또는 -M (등) gcc에 (-g의 추가). GCC plugin을 작성하여 일부 데이터베이스에서 원하는 정보를 수집하는 것도 고려해 볼 수 있습니다 (하지만 그만한 가치는 없을 것입니다). 당신은 또한 정보를 수집하기 위해이 build automation (예를 들어, 당신의 Makefile에 더 추가) 개선을 고려할 수 있습니다. 많은 대형 C 프로그램은 도구 (예 : bison) 또는 스크립트로 #line directives 번을 생성하여 .c 개의 파일이 포함되도록하고기술을 사용합니다. 그런 다음 어떤 파일 경로를 유지 하시겠습니까 ??

우리는 실행 파일을 만들기 위해 함께 컴파일 된 모든 파일을 쉽게 나열 할 수있는 절차를 찾고 있습니다.

해당 실행 파일을 작성하고 소스 코드에서 컴파일하는 경우 빌드시 해당 정보를 수집하는 것이 좋습니다. 그것은 몇 가지 timestamp.c 파일을 생성 아마로, gcc 일부 -M 및/또는 -H 플래그를 전달하는 것과 같은 사소한 수 (영감을 this를 볼 수 있지만 당신의 timestamp.c 포함 할 수있는 정보는 gcc -M 등 ...에서 제공). 타임 스탬프 파일에 git 버전 관리 메타 데이터 (예 : this Makefile에서 생성됨)가 포함될 수 있습니다. reproducible builds 및 약 package managers도 읽으십시오.

+0

답장을 보내 주셔서 감사합니다 ..하지만 어떻게 gdb 소스 코드를 추출하고 별도의 Windows (gdb -tui a.out) cgdb와 동일합니다. 시도하면 동일한 코드가 표시되는 것을 볼 수 있습니다 .. 디버거가 실제 소스 코드를 표시 할 수있는 방법. –

+0

어떻게 대답 할 수 있는지 설명해주었습니다. –

+0

Okzz ... 나는 당신의 요지를 얻었습니다 .. 당신에 따르면, 우리는 단지 파일 이름, 함수 이름, 라인 번호 등을 얻을 것입니다. 맞습니까? 그래서 어떻게 소스 파일 이름과 그 경로를 gdb의 도움으로 추출 할 수 있습니까? –