カジュアルにperlデバッガを使って捗る

toritori0318
2011-12-12

こんにちは。perlでほげほげするのが大好きなtoritori0318と申します。
さて突然ですが、みなさんはperlのデバッグをどのように行なっておりますでしょうか?

print+Data::Dumper で十分!という方から、
epicやPadreといったIDEでデバッグしたいよね、
アプリで出してるログ使ってるよー、
はたまた漢ならperl標準デバッガ使うべし、
など、いろいろなご意見があるでしょう。


自分はほとんどのケースでperl標準デバッガを使っています。
軽いし環境に依存しないし機能は十分だし最高!
ということで今回はPerl標準デバッガについて書いてみます。

デバッガの起動

perl -d <perlスクリプト>

簡単ですね!

デバッガコマンドの基本

もっと覚えるべきコマンドはたくさんありますが、
カジュアルに使う場合であればだいたいこのくらい覚えておけば十分かと思います。*1

実行系
c [行番号 or サブルーチン名] 指定された行またはサブルーチンまで処理を続ける
n ステップオーバー。サブルーチンをまたがって実行
s ステップイン。サブルーチンをたどって実行
r ステップアウト。現在のサブルーチンを抜けるまで実行
出力系
p [expr]   指定された式の値をprintする
x [expr]   指定された式の内容をリストコンテキストで解釈し、その内容をprintする
ブレークポイント関連
b [行番号 or サブルーチン名] ブレークポイントを設定
B [行番号] 指定された行番号のブレークポイントを削除する
B すべてのブレークポイントを削除する
表示系
v    周辺のソースコード確認。「.」を実行した後で「v」すると必ず現在行周辺のソースコードを確認できる
ブレークポイントの設定

以下のソースコード内に書いておくと、その行がブレークポイントになります。

$DB::single = 1;

ifで条件設定したり、warnやdieなどシグナル検知して設定することも
もちろん可能です。



さて、ここまでの知識でデバッグがだいぶ捗ると思いますが、
もう少し便利にデバッガを使ってみたいですよね!
なのでもうちょっとだけ続くのじゃよ。


デバッガ用設定ファイルを使ってみる

自分の場合ですが、デバッガに入った後必ず「{{ v」を実行します。
これを実行しておくとステップ実行しているときに毎回自動で周辺ソースコードを
表示してくれてだいぶ見やすくなります。

しかし、デバッガに入るときに毎回「{{ v」タイプするのは面倒ですよね!
そこでユーザホームディレクトリに .perldb というファイルを用意してあげると
デバッガのデフォルトの挙動を変更することができます。

たとえば上記の周辺ソースコード表示を行いたい場合は .perldb にこんなコードを書いておきます。*2

# デバッガの初期化終了後に呼び出されるサブルーチン
sub afterinit {
    # @DB::typeaheadにpushしておくと、TTY出力を模倣してくれる
    push @DB::typeahead, "{{ v";
}

または PERLDB_OPTS環境変数 を使っても似たような制御が可能です。
詳しくは後述のドキュメントをご参照下さい。

デバッガ自身をカスタマイズして自分色に染めてみる

えーそんなの難しいよー><
と思われるかもしれませんが、
実は以外と簡単にデバッガ自身のカスタマイズが行えるので紹介してみます。

まずはperl自身が使っているデバッガスクリプト「perl5db.pl」を適当なディレクトリにコピーしましょう。*3
そして、コピーしたファイルを適当にいじいじして
PERL5DB環境変数にカスタマイズスクリプトをロードする記述を入れてあげるだけです。

export PERL5DB='BEGIN { require "myperl5db.pl" }'

今回はデモということで以下のようなお遊びプロンプトを作ってみました\(^o^)/

パッチはこちらに置いておきますね。

正規表現/メモリ情報のデバッグ

正規表現のデバッグやメモリ情報のデバッグなどもありますが、
ハックな内容になりそうなのでここでは紹介しません。
こちらも続きはドキュメントにて。

おまけ1

perlでインタラクティブ実行したい時にはDevel::REPLのようなモジュールもありますが、
perl標準デバッガでも簡易的に実行できます。十分ですね。

perl -de 0

おまけ2

たとえばplack/psgiなアプリをデバッガ実行したい場合があるでしょう。
そんな時 「-S」 オプションを使うとplackupコマンドをフルパス指定する必要がなくなり、少しだけ捗りますね。*4

perl -Sd plackup MyApp.psgi

デバッグ関連ドキュメント(perldoc.jp)

さて、いかがでしたでしょうか?意外とデバッガも奥が深いですね。
さらに貪りたい方は以下のドキュメントを参考にすると
いままで知らなかったことがたくさん発見できるかも知れませんね!
https://perldoc.jp/docs/perl/5.10.0/perldebtut.pod
https://perldoc.jp/docs/perl/5.10.0/perldebug.pod




次はissmさんです!

*1: 足りない部分についてブログで補足する予定
*2: その他 .perldb の便利そうな記述については[https://gist.github.com/1455777:title=こちら]
*3: perlbrewを使っているなら「find ~/perl5 -name 'perl5db.pl'」でファイルが見つかるでしょう
*4: -Sオプション、実はさっき知りました><