この前、carton使ってたらなぜかsegmentation faultが起こって、なんでなんでってかんじでperlのデバッガを使って追いかけたって話をしたら、そういう時はgdbとかstraceとかを使ってセグフォってるところを見つけるところから始めたほうがよいと言われたので、ちょっとだけ勉強した。
Perlのコンパイル
インストールしているPerlを使ってやろうとしたら、上の記事で書かれているmy_perlというのが見えなくて、どうしようもなかったので、perlbrewでデバッグオプションとか最適化オプションとかを設定してPerlをコンパイルした。
perlbrew install --notest -v 5.14.2 --as=5.14.2d2 -DEBUGGING=-g -D optimize='-O0'
gdbでattach
上の記事に書いてある下のプログラムを動かして、gdbでattachしてみた。
#!/usr/bin/perl sub foo { my $a = $_[0]; print "$a\n"; while (1) { } } sub bar { foo("abc", "xyz", 999, 333.333); } bar();
gdb -p [process id]
とりあえずbt。
(gdb) bt #0 0x00000001000bd275 in Perl_pp_unstack () at pp_hot.c:220 #1 0x00000001000bc579 in Perl_runops_standard () at run.c:41 #2 0x0000000100020be1 in S_run_body (oldscope=1) at perl.c:2350 #3 0x0000000100020683 in perl_run (my_perl=0x802cd800000001) at perl.c:2268 #4 0x0000000100000bd0 in main (argc=2, argv=0x7fff5fbfddb0, env=0x7fff5fbfddc8) at perlmain.c:120
#3まで移動してmy_perlを覗く。
(gdb) p *my_perl $2 = { broiled = 0 '\0' }
何もなかった。うー。
ソースを見るとデフォルトでは、my_perlに使われている構造体が上のような物になっちゃうみたいでした。見れるようにするコンパイルオプションはよくわかりませんでした。
結論
いろいろやってみたけど、CとかC++とか全くやっていないせいで、あんまり理解できないまま終わりました。そのあたりの勉強をした後にまた勉強しなおしてみようかな。
なんか良い感じの勉強できる本とかあったら教えて下さい。