into the void

ソフトウェアに関する雑多な調査日記

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