glibcをデバッグしてみよう2
前回glibcを取ってきてそれをコンパイルしてみました。
そしてそのあと簡単なテストを作ってそのライブラリーをリンクしました。
今回はglibcの中に簡単な関数を作ってそれをgdbでデバッグしてみます。
mallocにhelloworldという関数を作ってみましょう。
glibcに関数を作るにはまずVersionsというファイルにその名前を書きます。
mallocフォルダーの中のVersionsにhelloworldを入れましょう。
malloc/Versions
.... # f* free; free2; # h* helloworld; # m* mallinfo; malloc; ....
次にmalloc.cの中にhelloworldを書いていきます。
malloc/malloc.c
int __libc_helloworld (void) { return 1; }
これだけではダメでhidden_protoとhidden_defに登録します。
malloc/malloc.c
int __libc_helloworld(void); libc_hidden_proto (__libc_helloworld) ..... libc_hidden_def (__libc_helloworld)
そして最後にこの関数にaliasを作ります。
malloc/malloc.c
strong_alias (__libc_helloworld, __helloworld) strong_alias (__helloworld, helloworld)
これでhelloworldがmallocの中に追加されました。 コンパイルしてみましょう。 今回はデバッグのオプションをつけてコンパイルします。
~/download/glibc-2.21/configure --prefix=/usr --enable-debug CFLAGS='-g -O2'
makeしてできたlibc.aにhelloworldが入っているか確かめてみましょう。
nm libc.a | grep helloworld 00000000000048c0 T __helloworld 00000000000048c0 T __libc_helloworld 00000000000048c0 T helloworld
入っています。ではこのhelloworldを呼び出してみましょう。
extern int helloworld (void); void * __gcc_personality_v0=0; void * _Unwind_GetIP=0; void * _Unwind_GetGR=0; void * _Unwind_GetCFA=0; void * _Unwind_Backtrace=0; void * _Unwind_Resume =0; void * __divdi3=0; void * __moddi3=0; int main(){ int res; res = helloworld(); return 0; }
前回のtest.cをちょっと変更しました。 helloworldを呼んでいるだけです。このtest.cを今コンパイルしたlibc.aとリンクしてコンパイルしてみましょう。 簡単にするためbuildディレクトリにあるlibc.aをtest.cのあるディレクトリにコピーしておきます。
cc -g -o test test.c -L./ -lc
コンパイルできたらgdbで実行してみましょう。
gdb test
ブレークポイントをhelloworldにおいてrunします。
b helloworld r
helloworldが1を返すのが確認できました。 いよいよglibcデバッグのお膳が整いました。では次回まで