gdbでデバッグ 〜stripとか-gオプションとか〜
gオプションをつけると生成されるバイナリにデバッグ情報が付加される。デバッグ情報とは、ソースコードへのパスやソースコード上の行番号。gdb上で行単位で実行をトレースすることができるようになる。
gオプションがないとgdbでデバッグできないわけではない、ただ表示される情報がシンボル単位になるだけ。
オブジェクトのシンボル情報は、リンクした後は削除することができる。stripコマンドを使ったり、-Wl,-sオプション付きでリンカをうごかしたりするとシンボルが削除される。オブジェクトファイルのサイズを縮小する目的で行われるが、これらのオブジェクトをgdbでデバッグしようとすると、表示される情報がライブラリ単位にまでさがる。
stripは実行形式のファイルに対して通常行うが、リンクする前のオブジェクトファイルに対しても行うことができる。ただ、リンクに必要なシンボル情報まで消えてしまうため、まともにリンクができなくなる。
stripをかけた後の実行形式ファイルにおいてもシンボルが全くなくなるわけではない。動的リンクに必要なシンボル情報は削除されずに残る。
usethread.c
#include <pthread.h> #include <unistd.h> #include <stdio.h> void* thread_func(void *param){ printf("start thread\n"); sleep(10); printf("end thread\n"); } void start_thread(){ pthread_t thread; pthread_create(&thread, NULL, thread_func, NULL); pthread_join(thread, NULL); } int main(void){ start_thread(); return 0; }
strip版
quetzal:~/binary$ readelf -s usethread_strip Symbol table '.dynsym' contains 8 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_create@GLIBC_2.2.5 (2) 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (3) 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3) 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_join@GLIBC_2.2.5 (2) 6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sleep@GLIBC_2.2.5 (3)
オリジナル版
quetzal:~/binary$ readelf -s usethread Symbol table '.dynsym' contains 8 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_create@GLIBC_2.2.5 (2) 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (3) 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3) 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_join@GLIBC_2.2.5 (2) 6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sleep@GLIBC_2.2.5 (3) Symbol table '.symtab' contains 78 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000400238 0 SECTION LOCAL DEFAULT 1 2: 0000000000400254 0 SECTION LOCAL DEFAULT 2 3: 0000000000400274 0 SECTION LOCAL DEFAULT 3 4: 0000000000400298 0 SECTION LOCAL DEFAULT 4 5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5 6: 0000000000400378 0 SECTION LOCAL DEFAULT 6 7: 00000000004003fc 0 SECTION LOCAL DEFAULT 7 8: 0000000000400410 0 SECTION LOCAL DEFAULT 8 9: 0000000000400450 0 SECTION LOCAL DEFAULT 9 10: 0000000000400468 0 SECTION LOCAL DEFAULT 10 11: 00000000004004e0 0 SECTION LOCAL DEFAULT 11 12: 00000000004004f0 0 SECTION LOCAL DEFAULT 12 13: 0000000000400550 0 SECTION LOCAL DEFAULT 13 14: 0000000000400774 0 SECTION LOCAL DEFAULT 14 15: 0000000000400780 0 SECTION LOCAL DEFAULT 15 16: 00000000004007a0 0 SECTION LOCAL DEFAULT 16 17: 00000000004007e0 0 SECTION LOCAL DEFAULT 17 18: 0000000000600e00 0 SECTION LOCAL DEFAULT 18 19: 0000000000600e08 0 SECTION LOCAL DEFAULT 19 20: 0000000000600e10 0 SECTION LOCAL DEFAULT 20 21: 0000000000600e18 0 SECTION LOCAL DEFAULT 21 22: 0000000000600ff8 0 SECTION LOCAL DEFAULT 22 23: 0000000000601000 0 SECTION LOCAL DEFAULT 23 24: 0000000000601040 0 SECTION LOCAL DEFAULT 24 25: 0000000000601050 0 SECTION LOCAL DEFAULT 25 26: 0000000000000000 0 SECTION LOCAL DEFAULT 26 27: 0000000000000000 0 SECTION LOCAL DEFAULT 27 28: 0000000000000000 0 SECTION LOCAL DEFAULT 28 29: 0000000000000000 0 SECTION LOCAL DEFAULT 29 30: 0000000000000000 0 SECTION LOCAL DEFAULT 30 31: 0000000000000000 0 SECTION LOCAL DEFAULT 31 32: 0000000000000000 0 SECTION LOCAL DEFAULT 32 33: 0000000000000000 0 FILE LOCAL DEFAULT ABS /usr/lib/gcc/x86_64-linux 34: 000000000040057c 0 FUNC LOCAL DEFAULT 13 call_gmon_start 35: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 20 __JCR_LIST__ 37: 00000000004005a0 0 FUNC LOCAL DEFAULT 13 deregister_tm_clones 38: 00000000004005d0 0 FUNC LOCAL DEFAULT 13 register_tm_clones 39: 0000000000400610 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux 40: 0000000000601050 1 OBJECT LOCAL DEFAULT 25 completed.6744 41: 0000000000600e08 0 OBJECT LOCAL DEFAULT 19 __do_global_dtors_aux_fin 42: 0000000000400630 0 FUNC LOCAL DEFAULT 13 frame_dummy 43: 0000000000600e00 0 OBJECT LOCAL DEFAULT 18 __frame_dummy_init_array_ 44: 0000000000000000 0 FILE LOCAL DEFAULT ABS usethread.c 45: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 46: 00000000004008c0 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__ 47: 0000000000600e10 0 OBJECT LOCAL DEFAULT 20 __JCR_END__ 48: 0000000000000000 0 FILE LOCAL DEFAULT ABS 49: 0000000000600e08 0 NOTYPE LOCAL DEFAULT 18 __init_array_end 50: 0000000000600e18 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC 51: 0000000000600e00 0 NOTYPE LOCAL DEFAULT 18 __init_array_start 52: 0000000000601000 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_ 53: 0000000000400770 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini 54: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_create@@GLIBC_2.2 55: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 56: 0000000000601040 0 NOTYPE WEAK DEFAULT 24 data_start 57: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5 58: 0000000000601050 0 NOTYPE GLOBAL DEFAULT 24 _edata 59: 0000000000400774 0 FUNC GLOBAL DEFAULT 14 _fini 60: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_ 61: 0000000000400688 54 FUNC GLOBAL DEFAULT 13 start_thread 62: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 24 __data_start 63: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 64: 0000000000601048 0 OBJECT GLOBAL HIDDEN 24 __dso_handle 65: 0000000000400780 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used 66: 00000000004006e0 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init 67: 0000000000601058 0 NOTYPE GLOBAL DEFAULT 25 _end 68: 0000000000400550 0 FUNC GLOBAL DEFAULT 13 _start 69: 000000000040065c 44 FUNC GLOBAL DEFAULT 13 thread_func 70: 0000000000601050 0 NOTYPE GLOBAL DEFAULT 25 __bss_start 71: 00000000004006be 21 FUNC GLOBAL DEFAULT 13 main 72: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_join@@GLIBC_2.2.5 73: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 74: 0000000000601050 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__ 75: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 76: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sleep@@GLIBC_2.2.5 77: 00000000004004e0 0 FUNC GLOBAL DEFAULT 11 _init
リンクする前にオブジェクトからシンボルを削除すると、リンクできなくなる。
quetzal:~/binary$ gcc -c usethread.c -o usethread.obj -g quetzal:~/binary$ strip usethread.obj quetzal:~/binary$ readelf -s usethread.obj quetzal:~/binary$ gcc -o usethread usethread.obj -lpthread /usr/bin/ld: error in usethread.obj(.eh_frame); no .eh_frame_hdr table will be created. /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 10 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 11 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 10 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 11 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 12 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 20 has invalid symbol index 20 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status