Blog

LL脳な人でもこれぐらいは覚えておくとうれしいgdbのつかいかた。または猫でもわかるgdb講座

LLつかってても「ばすえらーになるー」っていう状況ってたまにあるわけですが、LL しか普段つかわないゆとりは、ここでお手あげになってしまったりすることがままあります。

で、「ばすえらーになるんですが」ってときの最低限これだけはやってみたらどうか、という話。「えー、わたし gdb とかわかんないしー」とかいってる人でもこれぐらいならできるんじゃないかなーっと。


perl t/00_load.t

というコマンドで segv するという場合、gdb をつかって

% gdb --args perl t/00_load.t

とうつ。

すると、以下のようにプロンプトがでるので、"run" とうつ。これでスクリプトがはしりはじめる。

% gdb --args perl t/00_load.t
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tokuhirom/local/multiperl/5.8.9-DEBUGGING-usethreads/bin/perl...done.
(gdb)

そうすると、そのうちおちるでしょうと。

(gdb) run
Starting program: perl t/00_load.t
[Thread debugging using libthread_db enabled]
1..1
ok 1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
warning: Source file is more recent than executable.
6023

そしたら bt ってうつと、バックトレースがとれますよ、と。で、これをみると原因は Storable くさいということがわかりますよ、と。

(gdb) bt
#0  0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
#1  0x00007ffff613ab74 in pretrieve (my_perl=0x74d010, cv=<value optimized out>)
    at Storable.xs:6253
#2  XS_Storable_pretrieve (my_perl=0x74d010, cv=<value optimized out>)
    at Storable.xs:6452
#3  0x0000000000457e93 in Perl_pp_entersub (my_perl=0x74d010) at pp_hot.c:2862
#4  0x0000000000436ede in Perl_runops_debug (my_perl=0x74d010) at dump.c:1639
#5  0x00000000004539f6 in Perl_call_sv (my_perl=<value optimized out>,
    sv=0xa62ef0, flags=134) at perl.c:2731
#6  0x00007ffff5f274bb in faster_entersub (my_perl=<value optimized out>)
    at Faster.xs:47
#7  0x000000000044e1e6 in S_call_body (my_perl=0x74d010, myop=0xa161c0,
    is_eval=14 '\016') at perl.c:2801
#8  0x00000000004539f6 in Perl_call_sv (my_perl=<value optimized out>,
    sv=0x851230, flags=150) at perl.c:2731
#9  0x0000000000463ef2 in Perl_sv_clear (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4642
#10 0x00000000004646f5 in Perl_sv_free (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4862
#11 0x0000000000460142 in S_visit (my_perl=0x74d010,
    f=0x476740 <do_clean_objs>, flags=524288, mask=524288) at sv.c:370
#12 0x000000000046019f in Perl_sv_clean_objs (my_perl=0x7ffff613ac4e)
    at sv.c:471
#13 0x0000000000455f48 in perl_destruct (my_perl=<value optimized out>)
    at perl.c:881
#14 0x0000000000421cb0 in main (argc=3, argv=0x7fffffffe2b8, env=0x7fffffffe2d8)
    at perlmain.c:111

まあ、このぐらいの操作おぼえとくだけでも、XS が犯人か Perl そのものが犯人かは判定が容易にできる。XS が犯人だってわかれば、その周辺があやしいってのがすぐわかるんで、再現するコードをつくって、作者に報告すればいい(パッチをつくれるとなおいい)。

なお、perl 本体のぶぶんの行数とか表示させるには -DDEBUGGING つきで perl をコンパイルしておくことが必要。

なお、これ以上くわしいつかいかたは、http://d.hatena.ne.jp/stanaka/20080630/1214780557 のへんを参考にするといいですね。


なお Perl5 が SEGV する場合、1割は mod_perl に起因、9割5分は XS に起因、のこりの5分がperl本体に起因しています。ただし、のこりの5分のうち90%ぐらいはwell knownな問題です。http://perl-users.jp/articles/crashing_perl.html このへんには目をとおしておくとよいです。