gcc 디버그 기호(-g 플래그) vs linker's -rdynamic 옵션
glibc 제공backtrace()그리고.backtrace_symbols()실행 중인 프로그램의 스택 추적을 가져옵니다.하지만 이것이 작동하기 위해서는 링커의 프로그램을 사용해야 합니다.-rdynamic깃발을 올리다
사이의 차이점은 무엇입니까?-ggcc vs linker's에 전달된 플래그-rdynamicflag ? 샘플 코드의 경우 출력을 비교하기 위해 redelf를 했습니다.-rdynamic아래에서 더 많은 정보를 만들어 내는 것 같습니다.Symbol table '.dynsym'하지만 추가적인 정보가 무엇인지 잘 모르겠습니다.
설령 내가strip을 이용하여 만들어진 프로그램 바이너리.-rdynamic,backtrace_symbols()일을 계속합니다.
언제strip이진에서 모든 기호를 제거합니다. 왜 그것이 추가된 것을 뒤로하고 있습니까?-rdynamic깃발?
편집 : 아래 매트의 답변을 토대로 한 후속 질문..
당신이 찍은 것과 같은 샘플 코드에 대해 이것이 제가 보는 차이점입니다.-g&-rdynamic
선택의 여지없이..
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 70 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
와 함께-g더 많은 섹션, 더 많은 항목이 있습니다..symtab테이블 이지만.dynsym지금도 변함이 없습니다..
[26] .debug_aranges PROGBITS 0000000000000000 0000095c
0000000000000030 0000000000000000 0 0 1
[27] .debug_pubnames PROGBITS 0000000000000000 0000098c
0000000000000023 0000000000000000 0 0 1
[28] .debug_info PROGBITS 0000000000000000 000009af
00000000000000a9 0000000000000000 0 0 1
[29] .debug_abbrev PROGBITS 0000000000000000 00000a58
0000000000000047 0000000000000000 0 0 1
[30] .debug_line PROGBITS 0000000000000000 00000a9f
0000000000000038 0000000000000000 0 0 1
[31] .debug_frame PROGBITS 0000000000000000 00000ad8
0000000000000058 0000000000000000 0 0 8
[32] .debug_loc PROGBITS 0000000000000000 00000b30
0000000000000098 0000000000000000 0 0 1
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 77 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
와 함께-rdynamic추가 디버그 섹션은 없습니다. .symtab 항목은 70개(vanilla gcc 호출과 동일)이지만 그 이상입니다..dynsym항목..
Symbol table '.dynsym' contains 19 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 00000000005008e8 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
3: 0000000000400750 57 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
4: 00000000004005e0 0 FUNC GLOBAL DEFAULT 10 _init
5: 0000000000400620 0 FUNC GLOBAL DEFAULT 12 _start
6: 00000000004006f0 86 FUNC GLOBAL DEFAULT 12 __libc_csu_init
7: 0000000000500ab8 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
8: 00000000004006de 16 FUNC GLOBAL DEFAULT 12 main
9: 0000000000500aa0 0 NOTYPE WEAK DEFAULT 23 data_start
10: 00000000004007c8 0 FUNC GLOBAL DEFAULT 13 _fini
11: 00000000004006d8 6 FUNC GLOBAL DEFAULT 12 foo
12: 0000000000500ab8 0 NOTYPE GLOBAL DEFAULT ABS _edata
13: 0000000000500a80 0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
14: 0000000000500ac0 0 NOTYPE GLOBAL DEFAULT ABS _end
15: 00000000004007d8 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
16: 0000000000500aa0 0 NOTYPE GLOBAL DEFAULT 23 __data_start
17: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
18: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 70 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
이것들이 제가 가진 질문들입니다.
INGDB는 박트레이스를 얻기 위해 당신은 의심할 수 없습니다.그것이 단지 그것과 함께 작동한다면.
-g왜 우리가 필요합니까?-rdynamic역추적을 위해 _ symbols이 작동합니까?추가된 내용을 다음과
.symtab와 함께-g& 에의 추가..dynsym와 함께-rdynamic그들은 완전히 똑같지는 않습니다.둘 중 하나가 다른 하나에 비해 더 나은 디버깅 정보를 제공합니까? FWIW, 생성되는 출력의 크기는 다음과 같습니다: -g > with -rdynamic > with noth option..dynsym의 쓰임새는 정확히 무엇입니까?이 바이너리에서 내보낸 심볼이 전부입니까?그렇다면 foo가 .dynsym에 들어가는 이유는 우리가 라이브러리로 코드를 컴파일하고 있지 않기 때문입니다.
모든 정적 라이브러리를 사용하여 코드를 링크하면 backtrace_symbol이 작동하는 데 -rdynamic이 필요하지 않습니까?
문서에 따르면:
이것은 링커에게 사용된 기호뿐만 아니라 모든 기호를 동적 기호 테이블에 추가하도록 지시합니다.
디버그 기호가 아니라 동적 링커 기호입니다.이들은 다음에 의해 제거되지 않습니다.strip대부분의 경우 실행 파일이 깨지기 때문에 실행 파일의 마지막 링크 단계를 수행하기 위해 런타임 링커에 의해 사용됩니다.
예:
$ cat t.c
void foo() {}
int main() { foo(); return 0; }
없이 컴파일 및 링크하기-rdynamic(그리고 최적화는 분명히 없습니다.)
$ gcc -O0 -o t t.c
$ readelf -s t
Symbol table '.dynsym' contains 3 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 50 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400270 0 SECTION LOCAL DEFAULT 1
....
27: 0000000000000000 0 FILE LOCAL DEFAULT ABS t.c
28: 0000000000600e14 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
29: 0000000000600e40 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
실행 .symtab모든 것을 걸고하지만 주목할 것은.dynsym없습니다foo그 안에 최소한의 필수품이 들어 있습니다.다에 .backtrace_symbols일하기 위해.코드 주소를 함수 이름과 일치시키기 위해 해당 섹션에 있는 정보에 의존합니다.
합니다.-rdynamic:
$ gcc -O0 -o t t.c -rdynamic
$ readelf -s t
Symbol table '.dynsym' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
4: 0000000000601018 0 NOTYPE GLOBAL DEFAULT ABS _edata
5: 0000000000601008 0 NOTYPE GLOBAL DEFAULT 24 __data_start
6: 0000000000400734 6 FUNC GLOBAL DEFAULT 13 foo
7: 0000000000601028 0 NOTYPE GLOBAL DEFAULT ABS _end
8: 0000000000601008 0 NOTYPE WEAK DEFAULT 24 data_start
9: 0000000000400838 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
10: 0000000000400750 136 FUNC GLOBAL DEFAULT 13 __libc_csu_init
11: 0000000000400650 0 FUNC GLOBAL DEFAULT 13 _start
12: 0000000000601018 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
13: 000000000040073a 16 FUNC GLOBAL DEFAULT 13 main
14: 0000000000400618 0 FUNC GLOBAL DEFAULT 11 _init
15: 00000000004007e0 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
16: 0000000000400828 0 FUNC GLOBAL DEFAULT 14 _fini
Symbol table '.symtab' contains 50 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400270 0 SECTION LOCAL DEFAULT 1
....
27: 0000000000000000 0 FILE LOCAL DEFAULT ABS t.c
28: 0000000000600e14 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
29: 0000000000600e40 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
입니다..symtab,그러나 지금.foo는 동적 기호 섹션에 기호가 있습니다(그리고 지금은 여러 개의 다른 기호도 표시됩니다).는을 .backtrace_symbolswork - 이제 함수 이름으로 코드 주소를 매핑하기에 충분한 정보(대부분의 경우)를 가지고 있습니다.
벗기기:
$ strip --strip-all t
$ readelf -s t
Symbol table '.dynsym' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
4: 0000000000601018 0 NOTYPE GLOBAL DEFAULT ABS _edata
5: 0000000000601008 0 NOTYPE GLOBAL DEFAULT 24 __data_start
6: 0000000000400734 6 FUNC GLOBAL DEFAULT 13 foo
7: 0000000000601028 0 NOTYPE GLOBAL DEFAULT ABS _end
8: 0000000000601008 0 NOTYPE WEAK DEFAULT 24 data_start
9: 0000000000400838 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
10: 0000000000400750 136 FUNC GLOBAL DEFAULT 13 __libc_csu_init
11: 0000000000400650 0 FUNC GLOBAL DEFAULT 13 _start
12: 0000000000601018 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
13: 000000000040073a 16 FUNC GLOBAL DEFAULT 13 main
14: 0000000000400618 0 FUNC GLOBAL DEFAULT 11 _init
15: 00000000004007e0 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
16: 0000000000400828 0 FUNC GLOBAL DEFAULT 14 _fini
$ ./t
$
지금이다.symtab사라졌지만, 동적 기호 테이블은 그대로 있고, 실행 파일은 실행됩니다. 그래서backtrace_symbols여전히 효과가 있습니다.
동적 기호 테이블을 벗깁니다.
$ strip -R .dynsym t
$ ./t
./t: relocation error: ./t: symbol , version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference
... 그리고 부서진 실행 파일을 얻게 됩니다.
에 ..symtab그리고..dynsym사용되는 용도는 다음과 같습니다.내부 ELF 기호 테이블.주의할 점 중 하나는.symtab런타임에 필요하지 않으므로 로더에서 폐기합니다.해당 섹션은 프로세스의 메모리에 남아 있지 않습니다..dynsym, 반면, 이는 런타임 시에 필요하므로 프로세스 이미지에 유지됩니다.그래서 그것은 다음과 같은 것들에 이용 가능합니다.backtrace_symbols현재 프로세스에 대한 정보를 자체 내부에서 수집합니다.
그래서 간단히 말해서:
- 는 에 .
strip할 수 없게 만들 수 backtrace_symbols어떤 합니다에 속하는지 합니다.backtrace_symbols
그래서 당신이 알아차린 행동입니다.
구체적인 질문은 다음과 같습니다.
gdb디버거 입니다.실행 파일 및 라이브러리의 디버그 정보를 사용하여 관련 정보를 표시합니다.그것은 그것보다 훨씬 더 복잡합니다.backtrace_symbols파일도 , 합니다.backtrace_symbols실행 파일 이미지에 로드되지 않은 섹션에는 액세스할 수 없습니다.디버그 섹션은 런타임 이미지에 로드되지 않으므로 사용할 수 없습니다..dynsym디버깅 섹션이 아닙니다.다이내믹 링커가 사용하는 섹션입니다..symbtab디버깅 섹션도 아니지만 실행 파일(및 라이브러리)에 액세스할 수 있는 디버거에서 사용할 수 있습니다.-rdynamic디버그 섹션은 생성하지 않고 확장된 동적 심볼 테이블만 생성합니다.실행 가능한 성장성:-rdynamic실행 파일의 심볼 수(및 정렬/padding 고려 사항)에 전적으로 의존합니다.입니다.-g.- 정적으로 연결된 이진 파일을 제외하고 실행 파일은 로드 시 외부 종속성을 해결해야 합니다.하는 것처럼.
printfC 라이브러리에서 몇 가지 응용 프로그램 시작 절차를 제공합니다.이러한 다:입니다입니다..dynsym되며인이 exe가를 입니다..dynsym-rdynamic데. 합니다와 수 다른 가 추가됩니다.backtrace_symbols. backtrace_symbols정적으로 링크하는 경우 함수 이름을 확인하지 않습니다.-rdynamic,.dynsym섹션은 실행 파일로 내보내지 않습니다.obacktrace_symbols코드 주소를 기호에 매핑할 수 없습니다.
언급URL : https://stackoverflow.com/questions/8623884/gcc-debug-symbols-g-flag-vs-linkers-rdynamic-option
'programing' 카테고리의 다른 글
| Windows Powershell을 통해 새 파일 만들기 (0) | 2023.09.20 |
|---|---|
| 어디서 쓰였을까요?php come from, TinyMCE hack (0) | 2023.09.20 |
| uWSGI의 요점은 무엇입니까? (0) | 2023.09.20 |
| How big is the performance difference between Oracle and PostgreSQL? (0) | 2023.09.20 |
| 도커 - 0.0.0.0:4000에 대한 바인딩 실패: 포트가 이미 할당되었습니다. (0) | 2023.09.20 |