Ruby拡張ライブラリをデバッグする
静的リンクもしくは動的リンクでデバッグする方法があるようです。
今回は動的リンクでやってみました。
題材はpcaprubというRubyからpcapファイルを使うためのライブラリです。
ライブラリを使うa.rbから、test.pcapファイルを読み込むためにpcaprubを使います。
デバッグシンボルはあったほうがデバッグしやすいので、
拡張ライブラリを-gつきでコンパイルしておきます
gdbを起動します
$ gdb ruby
とりあえずmainにブレークポイントをはって、起動します
(gdb) b main (gdb) r a.rb test.pcap
Ruby は dln_loadでライブラリを読み込むようです
そこにもブレークポイントをはって、実行を再開します
(gdb) b dln_load
(gdb) c
ライブラリのロード部分でブレークします
encdb.soが読み込まれました
Breakpoint 2, dln_load (file=0x737400 "/home/yu74n/.../enc/encdb.so") at dln.c:1250
確認してみましょう*1
(gdb) i sharedlibrary From To Syms Read Shared Object Library (*snip*) 0x00007ffff619b680 0x00007ffff619c2b8 Yes /home/yu74n/.../enc/encdb.so
デバッグしたい拡張ライブラリが現れるまでスキップします
(gdb) c Continuing. Breakpoint 2, dln_load (file=0x8a9b90 "/home/yu74n/.../pcaprub.so") at dln.c:1250
現れたので確認してみます
(gdb) i sharedlibrary 0x00007ffff5d918c0 0x00007ffff5d94058 Yes /home/yu74n/.../pcaprub.so
ありましたね
あとはデバッグしたい場所にブレークポイントをはると
ブレークします
(gdb) b rbpcap_next_packet Breakpoint 3 at 0x7ffff5d92520: file pcaprub.c, line 802. (gdb) c Continuing. Breakpoint 3, rbpcap_next_packet (self=8914880) at pcaprub.c:802 warning: Source file is more recent than executable. 802 {
ソースを見てみます
(gdb) l 797 * If the next_packet() is unsuccessful, Null is returned. 798 */ 799 800 static VALUE 801 rbpcap_next_packet(VALUE self) 802 { 803 rbpcap_t *rbp; 804 rbpcapjob_t job; 805 char eb[PCAP_ERRBUF_SIZE]; 806 int ret;
*1:ブレークしてしばらくnextで進んだ後に実行してください