[pod] [xml]

NAME debug debugger

perldebug - Perl のデバッグ

DESCRIPTION

まず最初に一言「もう -w スイッチはお使いになりましたか。」

もし Perl デバッガに慣れていないなら、デバッガに関するチュートリアルである perldebtut を読んだ方がいいかもしれません。

The Perl Debugger

Perl を -d スイッチを付けて起動すれば、スクリプトは Perl ソースデバッガ 上で実行されることになります。 これは対話的な Perl 環境のように動作し、 ソースコードの表示、ブレークポイントの設定、スタックのバックトレース、 変数の値の変更、などを実行するデバッガコマンドを入力できます。 これはとても便利なので、単にやりたいことを対話的に試すために デバッガを起動するようになるでしょう。 例えば: -d

    $ perl -d -e 42

しかし、Perl デバッガは典型的なコンパイルされた環境の様に独立した プログラムではありません。 その代わりに、 -d フラグによって、コンパイラがインタプリタに渡すパース木にソース情報を 埋め込むようにしています。これは、ソースがデバッガ上で動作できるためには、 一度正常にコンパイルできないといけないということです。 それからインタプリタが起動され、デバッガを含む 特別な Perl ライブラリをロードします。

プログラムは、最初の実行時実行文の直前で停止し (ただし、以下コンパイル時実行文については後述します)、以下に示すいずれかの コマンドが入力されるのを待ちます。 よくある期待とは逆に、 デバッガが停止してある行のコードを表示しているときは、 直前に実行した行ではなく、常に今から実行する行を表示します。

デバッガが認識できないコマンドは現在のパッケージ内で Perl のコードとして 実行(eval)されます。 (デバッガは自分自身の状態を保存するために DB パッケージを使います。)

eval は暗黙のスコープで区切られていることに注意してください。 結果として、新しく導入されたレキシカル変数や変更された捕捉バッファの内容は eval の後失われます。 デバッガは Perl を学ぶよい環境ですが、もし同じスコープ内であるべき ものを使って対話的に実験したい場合は、それを 1 行に書いてください。

デバッガコマンドとして入力された文字列は、まず先頭と末尾の 空白が切り詰められます。 デバッガコマンドがプログラムの関数名と一致する場合、 関数名の前に ;+ のような、デバッガコマンドに見えない文字を 付け加えるか、括弧でくくってください。

Debugger Commands

(デバッガコマンド)

デバッガは以下のコマンドを理解します:

Configurable Options

(設定可能なオプション)

デバッガには O コマンドで設定できるさまざまなオプションがあります。 これは対話的、環境変数、rc ファイル (Unix では ./.perldb または ~/.perldb) で設定できます。

以下のオプションは V, X, x コマンドに影響を与えます。

rc ファイルが読み込まれた後、デバッガは $ENV{PERLDB_OPTS} 環境変数を 読み込み、デバッガのプロンプトから "O ..." として入力されたかのように パースします。 初期化オプション TTY, noTTY, ReadLine, NonStop も ここで設定できます。

rc ファイルに以下のように書くと:

  parse_options("NonStop=1 LineInfo=db.out AutoTrace");

スクリプトは人間の介入なしに実行され、トレース情報を db.out ファイルに出力します。 (中断して、何も表示されない場合は、LineInfo を /dev/tty に リセットしたほうがよいでしょう。)

以下に $ENV{PERLDB_OPTS} 変数を使った例を示します:

    $ PERLDB_OPTS="NonStop frame=2" perl -d myprogram

これは、人間の関与なしでスクリプト myprogram を実行し、進入と終了の ポイントの呼び出し木を表示します。 NonStop=1 frame=2N f=2 と等価で、もともとオプションは最初の文字 (Dump* オプションを法として) に省略できます。 それでもやはり、読みやすさと将来の互換性のために、常にフルスペルを書くことが 推奨されます。

もう一つの例としては:

    $ PERLDB_OPTS="NonStop LineInfo=listing frame=2" perl -d myprogram

とするとスクリプトは非対話的に実行され、サブルーチンへの進入と実行行を listing という名前のファイルに記録します。 (中断すると、何か「対話的」にするために LineInfo をリセットする方が 良いでしょう!)

(環境変数設定を表示する標準シェル構文を使った)もう一つの例としては:

  $ ( PERLDB_OPTS="NonStop frame=1 AutoTrace LineInfo=tperl.out"
      perl -d myprogram )

これは Term::ReadLine 地震を使っているプログラムをデバッグするのに 便利です。 以下のようなコマンドを使って、使用中のシェルを、/dev/ttyXX に対応する ウィンドウの TTY からデタッチすることを忘れないで下さい:

  $ sleep 1000000

詳細については perldebguts/"Debugger Internals" を参照してください。

Debugger input/output

(デバッガの入出力)

Debugging compile-time statements

(コンパイル時に実行される文のデバッグ)

コンパイル時に実行される文 (BEGIN と CHECK のブロック内のコードや use 文) があれば、それらはデバッガによって止めることができま せんrequire と INIT ブロックは可能です。 また、コンパイル時実行文は PERLDB_OPTSAutoTrace オプションを 設定することでトレースできます。 しかし、以下のような文を自分で Perl コードに含めれば、 デバッガに制御を渡すことができます。 この文は、デバッガを起動していないときには、何もしません:

    $DB::single = 1;

$DB::single に 2 をセットすると、nコマンドをタイプしたのと 等価になります。 1 を設定すると s コマンドとなります。 $DB::trace 変数は t コマンドをタイプした状態をシミュレートするために 1 にセットするべきです。

コンパイル時に実行されるコードをデバッグするもう一つの方法は、 モジュールの load にブレークポイントを設定して:

    DB<7> b load f:/perllib/lib/Carp.pm
  Will stop on load of `f:/perllib/lib/Carp.pm'.

(可能なら) R コマンドを使ってデバッガを再起動することです。 b compile subname も同じ目的に使えます。

Debugger Customization

(デバッガのカスタマイズ)

デバッガにはおそらくあなたが自分で修正する必要があるとは思わないような ところまで含んだ設定フックがあります。 デバッガの振る舞いは、デバッガ内で o コマンドを使って変更できます; これは PERLDB_OPT 環境変数経由でコマンドラインからか、設定ファイルから 変更できます。

初期化コードを入れたファイル .perldb を設定することでも、 いくらかのカスタマイズができます。 たとえば、以下のようなエイリアスが行えます (最後のものは、 人々があると思っているものです):

    $DB::alias{'len'}  = 's/^len(.*)/p length($1)/';
    $DB::alias{'stop'} = 's/^stop (at|in)/b/';
    $DB::alias{'ps'}   = 's/^ps\b/p scalar /';
    $DB::alias{'quit'} = 's/^quit(\s*)/exit/';

.perldb のオプションを、以下のような呼び出しによって変更できます:

    parse_options("NonStop=1 LineInfo=db.out AutoTrace=1 frame=2");

コードは DB パッケージで実行されます。 .perldb は PERLDB_OPTS の前に処理されることに注意してください。 .perldb で afterinit サブルーチンが定義されていると、この関数は デバッガの初期化終了後に呼び出されます。 .perldb はカレントディレクトリかホームディレクトリに置くことができます。 このファイルは Perl によって実行され、任意のコマンドを含めることが できるので、セキュリティ上の理由から、スーパーユーザーが現在のユーザーに よって所有され、所有者以外には書込み禁止になっていなければなりません。

@DB::typeahead に任意のコマンドを追加することで、デバッガへの TTY 入力を 模倣できます。 例えば、あなたの .perldb ファイルに以下のように書くと:

    sub afterinit { push @DB::typeahead, "b 4", "b 6"; }

デバッガ初期化の直後に 4 行目と 6 行目にブレークポイントを 設定しようとします。 @DB::typeahead はサポートしているインターフェースではなく、将来の リリースでは変更されることがあることに注意してください。

デバッガを変更したい場合には、perl5db.pl を Perl ライブラリから 別の名前にコピーし、修正してください。それから 環境変数 PERL5DB には、以下のように設定する必要があるでしょう:

    BEGIN { require "myperl5db.pl" }

最後の手段として、 PERL5DB を、直接内部変数を設定したり デバッガ関数を呼び出すことでデバッガをカスタマイズすることもできます。

このドキュメント(や perldebguts)に記述されていない変数や 関数は内部使用専用として扱われ、予告なく変更されることがあります。

Readline Support

(readline 対応)

出荷時の状態では、コマンドライン履歴参照機能として提供されるのは、 エクスクラメーションマークを付けることによる単純なものだけです。 しかし、CPAN から Term::ReadKey と Term::ReadLine のモジュールを インストールすることで、GNU readline(3) が提供するような 完全な編集機能が使えるようになります。 これらは CPAN の modules/by-module/Term ディレクトリにあります。 しかし、これらは通常の vi コマンドライン編集は対応していません。

基本的なコマンドライン補完も利用可能です。 残念ながら、レキシカル変数名は補完できません。

Editor Support for Debugging

(デバッグのためのエディタ対応)

FSF 版の emacs がシステムにインストールされている場合は、 C デバッガとの連携を連想させるような、Perl デバッガとの統合 ソフトウェア開発環境を提供します。

Perl には emacs を Perl の文法(の一部)を解釈する文法指向の エディタとして振舞わせるためのスタートファイルを同梱しています。 Perl ソース配布の emacs ディレクトリを参照してください。

ベンダー同梱の vi および X11 ウィンドウシステムと相互作用させるための Tom Christiansen による似たようなセットアップも利用可能です。 これは emacs が提供する統合マルチウィンドウサポートと同様に動作し、 デバッガがエディタを制御します。 しかし、これを記述している時点では、このツールの Perl 配布の中での 最終的な位置は不確定です。

vi ユーザーは、Perl のキーワードを色付けする、マウスとウィンドウ対応の vimgvim を調べてみてください。

perl のみが完全に Perl をパースできるので、これら全ての CASE ツールには 足りないところがあることに注意してください; 特に C プログラマーが書くような Perl プログラムを書いていない場合はそうです。

The Perl Profiler profile profiling profiler

(Perl プロファイラ)

Perl の実行に代替デバッガを使いたい場合は、単に -d オプションに コロンとパッケージからなる引数を付けてスクリプトを起動してください。 もっとも有名な Perl 用代替デバッガは Perl プロファイラです。 Devel::DProf は Perl 標準配布に含まれています。 ファイル mycode.pl にある Perl プログラムをプロファイリングしたい 場合、以下のようにします:

    $ perl -d:DProf mycode.pl

スクリプトが終了すると、プロファイラはプロファイル情報を tmon.out というファイルにダンプします。 Perl 標準配布に含まれている dprofpp のようなツールが、この プロファイルの情報を解釈するのに使えます。

Debugging regular expressions regular expression, debugging regex, debugging regexp, debugging

(正規表現のデバッグ)

use re 'debug' を指定すると、Perl 正規表現エンジンがどのように 動作するかの詳細を見ることができます。 この、典型的には大量の出力を理解するためには、 一般的に正規表現マッチがどのように行われるかだけでなく、 Perl の正規表現が内部的にどのようにオートマトンにコンパイルされるかを 知らなければなりません。 これらの事柄は詳細は perldebguts/"Debugging regular expressions" にあります。

Debugging memory usage memory usage

(メモリ使用のデバッグ)

Perl には自身のメモリ使用状況を報告するための内部機能があります。 しかしこれはかなり上級の概念で、メモリ割り当てがどのように行われるかに ついての理解が必要となります。 詳細については perldebguts/"Debugging Perl memory usage" を参照して下さい。

SEE ALSO

-w スイッチはもう使いましたよね?

perldebtut, perldebguts, re, DB, Devel::DProf, dprofpp, Dumpvalue, perlrun.

#! を使っているので普通は $PATH に見つかるスクリプトをデバッグするとき、 -S オプションを付けると perl は $PATH からスクリプトを探すので、 パスや which $scriptname をタイプする必要がなくなります。

  $ perl -Sd foo.pl

BUGS

C や C++ 拡張のような、Perl でコンパイルされていないものに対して スタックフレーム情報やあらゆるデバッグ関数を使うことはできません。

サブルーチン内で(shiftpop を使って) @_ 引数を変更した場合、 スタックバックトレースで元の値を表示することはできません。

デバッガは現在のところ -W コマンドラインスイッチと同時に 使うことはできません。これ自身が警告から逃れられないからです。

(キーボードやソケットからの wait, accept, readなどの) 遅いシステムコールを実行中で、独自の $SIG{INT} ハンドラを設定していない場合、 デバッガに戻ってくるために CTRL-C を使うことはできません。 これは、デバッガ自身の $SIG{INT} ハンドラが 遅いシステムコールから longjmp(3) で出るための例外を発生させる必要性を 理解しないからです。