perldebug - Perl のデバッグ
まず最初に一言「もう -w スイッチはお使いになりましたか。」
もし Perl デバッガに慣れていないなら、デバッガに関するチュートリアルである perldebtut を読んだ方がいいかもしれません。
Perl を -d スイッチを付けて起動すれば、スクリプトは Perl ソースデバッガ 上で実行されることになります。 これは対話的な Perl 環境のように動作し、 ソースコードの表示、ブレークポイントの設定、スタックのバックトレース、 変数の値の変更、などを実行するデバッガコマンドを入力できます。 これはとても便利なので、単にやりたいことを対話的に試すために デバッガを起動するようになるでしょう。 例えば:
$ perl -d -e 42
しかし、Perl デバッガは典型的なコンパイルされた環境の様に独立した プログラムではありません。 その代わりに、 -d フラグによって、コンパイラがインタプリタに渡すパース木にソース情報を 埋め込むようにしています。これは、ソースがデバッガ上で動作できるためには、 一度正常にコンパイルできないといけないということです。 それからインタプリタが起動され、デバッガを含む 特別な Perl ライブラリをロードします。
プログラムは、最初の実行時実行文の直前で停止し (ただし、以下コンパイル時実行文については後述します)、以下に示すいずれかの コマンドが入力されるのを待ちます。 よくある期待とは逆に、 デバッガが停止してある行のコードを表示しているときは、 直前に実行した行ではなく、常に今から実行する行を表示します。
デバッガが認識できないコマンドは現在のパッケージ内で Perl のコードとして 実行(eval
)されます。 (デバッガは自分自身の状態を保存するために DB パッケージを使います。)
eval
は暗黙のスコープで区切られていることに注意してください。 結果として、新しく導入されたレキシカル変数や変更された捕捉バッファの内容は eval の後失われます。 デバッガは Perl を学ぶよい環境ですが、もし同じスコープ内であるべき ものを使って対話的に実験したい場合は、それを 1 行に書いてください。
デバッガコマンドとして入力された文字列は、まず先頭と末尾の 空白が切り詰められます。 デバッガコマンドがプログラムの関数名と一致する場合、 関数名の前に ;
や +
のような、デバッガコマンドに見えない文字を 付け加えるか、括弧でくくってください。
デバッガを呼び出すにはいくつかの方法があります:
program_name
で識別されるプログラムに対して。
-e
を使って指定された任意の expression
を対話的に。
Devel::Ptkdb
GUI 経由で与えられたプログラムをデバッグする。
スレッドを使っているプログラムをデバッグする(実験的機能)。
対話式のデバッガは以下のコマンドを理解します:
サマリヘルプメッセージを表示します。
指定されたコマンドの説明を表示します。
h h
という特別なコマンドは、かなり長い、ヘルプ全体を表示します。
h h
コマンド(や他のコマンドでも)の出力で画面がスクロールしてしまう場合、 以下のようにコマンドの前にパイプ記号をつけるとページャーを呼び出します:
DB> |h h
使用されるページャーは O pager=...
コマンドで変更できます。
現在のパッケージでの print {$DB::OUT} expr
と同じです。 特に、これは Perl 自身の print
関数なので、 x
コマンドと違って、ネストしたデータ構造やオブジェクトはダンプしません。
STDOUT がどこにリダイレクトされていても、 ファイルハンドル DB::OUT
は /dev/tty に対して オープンされています。
式をリストコンテキストで評価し、結果を多少読みやすい形で表示します。 ネストしたデータは再帰的に表示します。 これは Perl の実際の print
関数とは異なります。 When dumping hashes, you'll probably prefer 'x \%h' rather than 'x %h'. これを自分自身で行いたい場合は Dumpvalue を参照して下さい。
出力フォーマットは "Configurable Options" に記された 様々なオプションの影響を受けます。
maxdepth
が指定されている場合、それは数値 N でなければなりません; dumpDepth
オプションが一時的に N に設定されたかのように、 値は N レベルの深さでだけダンプされます。
package (デフォルトは main
) 内のすべて (または、一部) の 変数 (variable) をデータプリティプリンタを使って表示します (ハッシュは何が何か解るように、key と value を表示し、 コントロール文字は表示できる形にします)。 以下に示すように、symbol は名前だけを示し、($
などの) 型識別子を 付けないようにしてください:
V DB filename line
正と逆の正規表現のためには ~pattern
と !pattern
を使ってください。
これは有効な変数のそれぞれについて x
を呼び出すのと似ています。
V 現在のパッケージ [vars]
と同じです。
現在のスコープや、level だけ高いスコープの全て(またはいくつか)の レキシカル変数を表示します(記憶法: mY
変数)。 V
や X
コマンドと全く同じように、vars を制定することで 表示される変数を制限できます。 バージョン 0.08 以降の PadWalker
モジュールが必要です; もしインストールされていなければ警告されます。 出力は V
コマンドと同じスタイルにフォーマットされ、 このフォーマットは同じオプションで制御されます。
スタックのバックトレースを行います。出力についての詳細は後述します。
シングルステップ実行します。 サブルーチンをたどりながら、別の実行文の先頭に到達するまで実行します。 関数呼び出しを含む式が与えられた場合、これもシングルステップ実行します。
ネクスト。次の実行文の先頭に到達するまで、サブルーチンにまたがって実行します。 関数呼び出しを含む式が与えられた場合、 各行毎に停止しながら関数を実行します。
現在のサブルーチンから戻るまで実行します。 PrintRet
がセットされていれば(デフォルトではセットされています) 返り値をダンプします。
最後の n
または s
を繰り返します。
続きを実行します。 オプションとして、1 回限りのブレークポイントを 指定された行またはサブルーチンに設定します。
次の 1 画面分をリスト表示します。
min
から incr+1
行をリスト表示します。
min
行から max
行をリスト表示します。 l -
は -
と同じです。
指定行をリスト表示します。
サブルーチンの最初の一画面分をリスト表示します。 subname は コードリファレンスが入った変数でも構いません。
前の 1 画面分をリスト表示します。
指定行付近の(数行のコードをリスト表示します。
最後に実行した行への内部デバッガポインタを返し、 その行を表示します。
異なるファイルまたは eval
行に表示を切り替えます。 もし filename が %INC にあるフルパス名でなければ、 正規表現として扱われます。
eval
した文字列は(アクセス可能なら)ファイル名として扱われます: f (eval 7)
と f eval 7\b
は (実行した順で) 7 番目に eval
した 文字列の中身にアクセスします。 現在実行した eval
の中身と、サブルーチンを定義する eval
した 中身は保存されるので、アクセス可能です。
pattern を用いて Perl 正規表現による前方検索を行います。 最後の / はなくてもかまいません。 デフォルトでは検索は大文字小文字を区別しません。
pattern を用いて後方検索を行います。 最後の ? はなくてもかまいません。 デフォルトでは検索は大文字小文字を区別しません。
ブレークポイント、アクション、ウォッチ式を (デフォルトは全て)リストアップします。
regex に一致する(または一致しない)サブルーチン名をリストアップします。
トレースモードの on/off を切り替えます。(AutoTrace
オプションも参照して下さい)
expr
の実行をトレースします。 例については "Frame Listing Output Examples" in perldebguts を 参照して下さい。
現在の位置にブレークポイントを設定します。
与えられた行の直前にブレークポイントを設定します。 condition が指定されると、その文にさしかかる度に評価されます。 condition が真となったときにだけブレークポイントが働きます。 ブレークポイントは、実行可能な文で始まる行にだけ、 設定できます。 condition には if
を使いません:
b 237 $x > 30
b 237 ++$count237 < 11
b 33 /pattern/i
サブルーチンの最初の実行可能文にブレークポイントを設定します。 subname は コードリファレンスが入った変数でも構いません (この場合は condition は非対応です)。
コンパイル後、サブルーチンの最初の行にブレークポイントをセットします。
filename の最初に実行される行の手前にブレークポイントをセットします。 これは %INC の値に含まれるフルパス名であるべきです。
指定されたサブルーチンがコンパイルされた後、最初に実行される文の手前に ブレークポイントをセットします。
line で指定されたブレークポイントを削除します。
すべてのブレークポイントを削除します。
その行を実行する前に行うアクションを設定します。 line が省略されると、いままさに実行しようとしていた行に アクションを設定します。 デバッガが実行する処理の順番は以下の通りです。
1. この行のブレークポイントをチェックします
2. 必要なら行を表示します(トレース)
3. この行に結び付けられたアクションを実行します
4. ブレークポイントやシングルステップの場合はユーザーに確認します
5. 行を評価します
例えば、以下のコードは 53 行を通過する毎に $foo を表示します。
a 53 print "DB FOUND $foo\n"
指定された行に設定されたアクションを削除します。 line が省略されると、いままさに実行しようとしている行に設定されている アクションが削除されます。
設定されたすべてのアクションを削除します。
グローバルなウォッチ式を追加します。 グローバルな変更が行われたときは、デバッガは停止して新旧の値を表示します。
ウォッチ式を削除します。
全てのウォッチ式を削除します。
全てのオプションを表示します。
リストされた各真偽値オプションの値を 1
に設定します。
1 つ、あるいは複数のオプションの値を表示します。
一つまたは複数のオプションをセットします。 値自身に空白を含む場合、クォートする必要があります。 例えば、less をオプション付きで呼び出す場合は o pager="less -MQeicsNfr"
のようにします。 シングルクォートとダブルクォートのどちらでも使えますが、クォートする場合は、 クォート文字と同じ文字はエスケープする必要があります; そしてエスケープ文字自身もエスケープして、クォート文字を エスケープしているのではないことを示す必要があります。 言い換えると、クォートに関わりなく、シングルクォートルールに従います; 例えば: o option='this isn\'t bad'
や o option="She said, \"Isn't it?\""
歴史的な理由により、=value
は省略可能ですが、そうするのが安全な場合にのみ デフォルトは 1 です -- これは、ほとんどの場合ブール値オプションです。 =
を使って指定した値を代入する方が常によいです。 option
は短縮できますが、明確化のためにはそうしない方がいいでしょう。 いくつかのオプションは互いにセットできます。 それらの一覧については "Configurable Options" を参照してください。
プロンプト表示前に実行するアクションを全て表示します。
デバッガがプロンプトを出す直前に、毎回実行するアクション (Perl のコマンド)を設定します。 複数行の command は、バックスラッシュと改行で書くことができます。
プロンプト表示前に実行するアクションを全て削除します。
デバッガがプロンプトを出す直前に、毎回実行するアクション (Perl のコマンド)を追加します。 複数行の command は、バックスラッシュと改行で書くことができます。
プロンプト表示後に実行するアクションを全て表示します。
スクリプトの実行に戻るコマンドを入力した時に、デバッガが プロンプトを出した後で、毎回実行するアクション(Perl のコマンド)を設定します。 複数行の command は、バックスラッシュと改行で書くことができます (きっとあなたは今までこのことを知らなかったはずです)。
プロンプト表示後に実行するアクションを全て削除します。
スクリプトの実行に戻るコマンドを入力した時に、デバッガが プロンプトを出した後で、毎回実行するアクション(Perl のコマンド)を追加します。 複数行の command は、バックスラッシュと改行で書くことができます。
プロンプト表示前に実行するデバッガコマンドを表示します。
デバッガがプロンプトを出す前に、毎回実行するアクション(デバッガの コマンド)を設定します。 複数行の command は、いつもの方法で書くことができます 警告 もし command
がないと、全てのアクションが消えてしまいます!
このコマンドはある意味新しいので、もし代わりに間違ってブロックを 入力したように見えるときには、警告が出ます。 本当に奏したい場合は、;{ ... }
か、いっそ do { ... }
と 書いてください。
プロンプト前に実行するデバッガコマンドを全て削除します。
毎回デバッガプロンプトを表示する前に実行するアクション(デバッガコマンド)を 追加します。予測可能な方法な方法で複数行コマンドも登録できます: 上記を参照してください。
以前のコマンドを再実行します。(number が省略されると、直前のコマンドを実行します)
指定数値分前のコマンドを実行します。
pattern で始まるうち、最も最近に実行されたコマンドを 再実行します。 O recallCommand
も参照して下さい。
cmd をサブプロセスとして実行します(DB::IN から読み込み、DB::OUT に書き出します)。 O shellBang
も参照してください。 ユーザーの現在のシェル(つまり、 $ENV{SHELL}
変数)が使われるので、 終了コードの適切な解釈やシグナルとコアダンプの情報が妨害されるかもしれない ことに注意してください。
デバッガコマンドを file から読み込んで実行します。 file 自身に source
コマンドを含んでいても構いません。
最近の指定数値分のコマンドを表示します。 2 文字以上のコマンドのみが表示されます。 number が省略されると、全てを表示します。
デバッガを終了します。 (エイリアスを設定しない限り、"quit" はこの目的には使えません。) これはデバッガを終了する唯一の方法ですが、exit
を2回 入力しても動作します。
スクリプトの最後にステップ実行できるようにしたい場合は、 inhibit_exit
オプションに 0 を設定してください。 グローバルなデストラクタを実行してステップ実行したい場合は、 $finished に 0 を設定する必要があります。
新しいセッションを exec()
することでデバッガを再起動します。 履歴は残そうと努力しますが、内部設定やコマンドラインオプションは 失われるかもしれません。
今のところ、以下の設定は保存されます: 履歴、ブレークポイント、アクション、 デバッガオプション、Perl コマンドラインオプション -w, -I, -e。
デバッガコマンドを実行し、DB::OUT をパイプであなたの現在のページャと繋ぎます。
|dbcmd
と同様ですが、 DB::OUT は一時的に select
で 選択されているものになります。
以下のようにコマンドエイリアスを定義する:
= quit q
または現在のエイリアスの一覧を表示します。
command を Perl の文として実行します。文末のセミコロンはなくてもかまいません。 Perl の文が Perl デバッガにとって紛らわしい場合は 先頭にセミコロンをつけてください。
評価した表現の結果が呼び出されたメソッドを一覧表示します。 表現は bless されたオブジェクトへのリファレンスか、パッケージ名として 評価されます。
読み込まれたモジュールとバージョンを全て表示します。
その名前にも関わらず、これは与えられたページ(manpage が省略された 場合はビューワ自身)に対してシステムのデフォルトのドキュメントビューワを 呼び出します。 ビューワが man の場合、適切な MANPATH や -M manpath オプションを使って man を起動するために、現在の Config
情報が 使われます。 XXX
の形で一致する man ページの検索に失敗した場合、 perlXXX の形のものを再検索します。 これにより、デバッガから man debug
や man op
と タイプできるようになります。
伝統的に利用可能な man コマンドを奪われたシステムでは、デバッガは< perldoc を起動します。 反抗的なベンダーや、より適切には、積極的なユーザーによって、この判断は 正しくありません。 もしあなたがどちらかの分類に当てはまってしまうなら、Perl のドキュメントを 表示するためにどのビューワを使うかを、手動で $DB::doccmd 変数に セットしてください。 これは rc ファイルででも、直接の代入ででもセットできます。 私たちは以下のような感じで、実際に動作する例を待っています:
$DB::doccmd = 'netscape -remote http://something.here/';
デバッガには O
コマンドで設定できるさまざまなオプションがあります。 これは対話的、環境変数、rc ファイル (Unix では ./.perldb または ~/.perldb) で設定できます。
recallCommand
, ShellBang
再呼び出しコマンドとシェル起動に使われる文字です。 デフォルトでは、残念ながら、両方とも !
にセットされています。
pager
ページャにパイプされるコマンド(文字 |
で始まるもの)の出力に 使われるプログラム。 デフォルトでは、$ENV{PAGER}
が使われます。 デバッガは強調と下線に関して現在の端末設定を使うので、もし選択した ページャがエスケープシーケンスを変更せずに通過させられない場合、 一部のデバッガコマンドの出力は、ページャに送られると読めなくなるでしょう。
tkRunning
プロンプトで (ReadLine と共に) Tk を実行します。
signalLevel
, warnLevel
, dieLevel
詳細さのレベル。 デフォルトでは、デバッガは例外と警告を放っておきます; これを変更すると、プログラムが正しく動かなくなることがあるからです。 捕捉されていない INT, BUS, SEGV シグナルがあると、メッセージを 表示しようとします。 (しかし、以下の BUGS のシグナルに関する注意を参照してください。)
このデフォルトのセーフモードを無効にするには、これらの値を 0 以上に セットしてください。 レベル 1 では、あらゆる種類の警告(これはしばしばうんざりさせるものです)や 例外(これはしばしば価値があります)を受信した時にバックトレースを得ます。 残念ながら、デバッガは致命的な例外と致命的でない例外を識別できません。 dieLevel
は 1 であっても、致命的でない例外もトレースされ、 それが eval された
文字列からか、読み込もうとしたモジュール内の あらゆる種類の eval
からのものであるなら、突然置き換えられます。 dieLevel
が 2 なら、デバッガは例外の出所を気にしません: 例外ハンドラを横取りしてトレースを表示し、それから全ての例外を自身の装飾で 修正します。 これはある種のトレースの目的にはおそらく有用ですが、 例外をまじめに扱っているプログラムをどうしようもなく破壊してしまう傾向が あります。
AutoTrace
トレースモード(t
コマンドと同様ですが、PERLDB_OPTS
に書けます)。
LineInfo
行番号情報を記録するファイルまたはパイプ。 これが (|visual_perl_db
のように) パイプの場合、短い文章が使われます。 これは、特別な vi
や emacs
のフックや、ddd
グラフィカル デバッガのようなスレーブエディタやビジュアルデバッガと相互作用するために 使われる機構です。
inhibit_exit
0 だと、スクリプトの最後で プログラムを終了する ことを認めます。
PrintRet
設定されると(デフォルト)、r
コマンドの後に返り値を表示します。
ornaments
コマンドラインの画面への表示に影響を与えます(Term::ReadLine を 参照してください)。 今のところ、これを無効にする方法はありません; これにより、ディスプレイやページャーによっては判読できない出力を 行うことがあります。 これはバグと考えられています。
frame
サブルーチンへの出入り時のメッセージ表示に影響を与えます。 frame & 2
が偽なら、サブルーチンに入る時にのみメッセージを出力します。 (出るときのメッセージは、他のメッセージがまき散らされているときには 有用でしょう。)
frame & 4
の場合、関数の引数に加えて、コンテキストと呼び出し元の 情報を表示します。 frame & 8
の場合、引数の表示にオーバーロードされた 文字列化
と tie
した FETCH
が有効になります。 frame & 16
の場合、サブルーチンからの返り値が表示されます。
引数リストが切り詰められた時の長さは次のオプションの管轄となります:
maxTraceLen
frame
オプションの bit 4 がセットされている時の引数リストを切り詰める 長さ。
windowSize
コードリストウィンドウの大きさを変更します(デフォルトは 10 行です)。
以下のオプションは V
, X
, x
コマンドに影響を与えます。
arrayDepth
, hashDepth
最初の N 要素だけを表示します('' を指定すると全て表示します)。
dumpDepth
構造をダンプするときに再帰の深さを N レベルに制限します。 負数を指定すると無限として解釈されます。 デフォルト: 無限。
compactDump
, veryCompact
配列とハッシュの出力スタイルを変更します。 compactDump
の場合は、短い配列は 1 行で表示します。
globPrint
グロブの内容を表示するかどうかです。
DumpDBFiles
デバッグしていているファイルが保持している配列をダンプします。
DumpPackages
パッケージのシンボルテーブルをダンプします。
DumpReused
「再利用された」アドレスの内容をダンプします。
quote
, HighBit
, undefPrint
文字列ダンプのスタイルを変更します。 quote
のデフォルトは auto
です; "
や '
にセットすることでダブルクォート風やシングルクォート風に できます。 デフォルトでは、最上位ビットがセットされている文字はそのまま表示されます。
UsageOnly
基本的なパッケージ単位のメモリ使用量ダンプ。 パッケージ内の変数で見つかった文字列のサイズの合計を計算します。 モジュールのファイルスコープ内のレキシカルや、クロージャ内で 失われたものは含まれません。
rc ファイルが読み込まれた後、デバッガは $ENV{PERLDB_OPTS}
環境変数を 読み込み、デバッガのプロンプトから "O ..." として入力されたかのように パースします。 初期化オプション TTY
, noTTY
, ReadLine
, NonStop
も ここで設定できます。
rc ファイルに以下のように書くと:
parse_options("NonStop=1 LineInfo=db.out AutoTrace");
スクリプトは人間の介入なしに実行され、トレース情報を db.out ファイルに出力します。 (中断して、何も表示されない場合は、LineInfo
を /dev/tty に リセットしたほうがよいでしょう。)
TTY
デバッグ I/O として TTY を使います。
noTTY
セットすると、デバッガは NonStop
モードとなり、TTY と接続されません。 もし中断された(または Perl スクリプトから明示的に $DB::signal や $DB::single をセットすることによってデバッガに制御が移った)場合、 起動時に TTY
オプションで指定された TTY か、実行時に Term::Rendezvous
モジュールで選択された TTY に接続されます。
このモジュールは、2 つのメソッド IN
と OUT
をもつオブジェクトを 返すメソッド new
を実装する必要があります。 これらはそれぞれ、デバッグ入力と出力のためのファイルハンドルを 返すようにします。 new
メソッドは起動時に $ENV{PERLDB_NOTTY}
の値を含んでいる 引数を検査し、さもなければ "$ENV{HOME}/.perldbtty$$"
となります。 このファイルは適切な所有権について検査されないので、 理論的にはセキュリティの問題が起こり得ます。
ReadLine
偽だと、デバッグするアプリケーション自身が ReadLine を使うために、 readline 対応を無効にします。
NonStop
設定されると、デバッガは中断されるか、プログラム的に $DB::signal か $DB::single に設定されるまで、非対話的モードとなります。
以下に $ENV{PERLDB_OPTS}
変数を使った例を示します:
$ PERLDB_OPTS="NonStop frame=2" perl -d myprogram
これは、人間の関与なしでスクリプト myprogram を実行し、進入と終了の ポイントの呼び出し木を表示します。 NonStop=1 frame=2
は N 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
詳細については "Debugger Internals" in perldebguts を参照してください。
デバッガのプロンプトは以下のようだったり:
DB<8>
あるいは以下のようだったりします:
DB<<17>>
ここで数値はコマンド番号で、組み込みの csh 風履歴機構を使って アクセスするのに使います。 例えば、!17
はコマンド番号 17 を再実行します。 不等号の深さはデバッガのネストの深さを示します。 例えば、既にブレークポイントにいて、それ自身にもブレークポイントを 含む関数呼び出しの結果を表示させたり、s/n/t expression
コマンドを 使って式をステップ実行したりした時に複数の不等号の組を見ることがあります。
複数の文からなるサブルーチン定義やフォーマットといった、複数行の コマンドを入力したい場合は、通常はデバッガコマンドを終了させる改行を バックスラッシュでエスケープしてください。 以下は例です:
DB<1> for (1..4) { \
cont: print "ok\n"; \
cont: }
ok
ok
ok
ok
この、改行をエスケープする問題は、対話的にデバッガに入力されたコマンドに 特有であることに注意してください。
これは、T
コマンドによって表示されるスタックバックトレースの 例です:
$ = main::infested called from file `Ambulation.pm' line 10
@ = Ambulation::legs(1, 2, 3, 4) called from file `camel_flea' line 7
$ = main::pests('bactrian', 4) called from file `camel_flea' line 4
上記の左側の文字は関数が呼び出されたコンテキストを示しています; $
と @
はそれぞれスカラコンテキストとリストコンテキストを意味し、 .
は無効コンテキスト(実際のところはスカラコンテキストのようなもの)を 意味します。 上記の表示は、スタックダンプを実行したときに main::infested
にいて、 これはファイル Ambulation.pm の 10 行目から、スカラコンテキストで 引数なしで呼び出されています; つまり &infested
のようにして 呼び出されています。 次のスタックフレームは、関数 Ambulation::legs
が camel_flea から リストコンテキストで 4 つの引数と共に呼び出されています。 最後のスタックフレームは、main::pests
が、同じファイル camel_flea の 4 行目からスカラコンテキストで呼び出されています。
有効な use
文の中から T
コマンドを実行すると、バックとレースには require
フレームと eval
フレームの両方が含まれます。
これは l
コマンドの出力を示しています:
DB<<13>> l
101: @i{@i} = ();
102:b @isa{@i,$pack} = ()
103 if(exists $i{$prevpack} || exists $isa{$pack});
104 }
105
106 next
107==> if(exists $isa{$pack});
108
109:a if ($extra-- > 0) {
110: %isa = ($pack,1);
ブレーク可能な行には :
が付いています。 ブレークポイントのある行には b
が、アクションがある行には a
があります。 今から実行しようとしている行には ==>
が付いています。
デバッガで表示されるコードは、元のソースコードと同じように見えるとは 限らないことに注意してください。 行指示子と外部ソースフィルタが、Perl がコードを見る前にコードを 変更することがあり、それによってコードが元の位置から移動したり、 完全に異なる形になったりします。
frame
オプションが設定されると、デバッガはサブルーチンに入ったとき (および出たときもオプションで)違ったスタイルで表示します。 これらの非常に長い例については perldebguts を参照してください。
コンパイル時に実行される文 (BEGIN, UNITCHECK, CHECK のブロック内のコードや use
文) があれば、それらはデバッガによって止めることができま せん。require
と INIT ブロックは可能です。 また、コンパイル時実行文は PERLDB_OPTS
で AutoTrace
オプションを 設定することでトレースできます。 しかし、以下のような文を自分で 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
も同じ目的に使えます。
デバッガにはおそらくあなたが自分で修正する必要があるとは思わないような ところまで含んだ設定フックがあります。 デバッガの振る舞いは、デバッガ内で 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)に記述されていない変数や 関数は内部使用専用として扱われ、予告なく変更されることがあります。
出荷時の状態では、コマンドライン履歴参照機能として提供されるのは、 エクスクラメーションマークを付けることによる単純なものだけです。 しかし、(Term::ReadLine::Gnu, Term::ReadLine::Perl, ... のように) CPAN から Term::ReadKey と Term::ReadLine のモジュールを インストールすることで、GNU readline(3) が提供するような 完全な編集機能が使えるようになります。 これらは CPAN の modules/by-module/Term ディレクトリにあります。 しかし、これらは通常の vi コマンドライン編集は対応していません。
基本的なパッケージ単位のメモリ使用量ダンプ; PadWalker
モジュールが インストールされているなら現在のスコープのレキシカル変数も含みます。
Readline 対応なしでは、矢印キーやバックスペースキーを使うと "^[[A", "^[[C", "^[[B", "^[[D"", "^H" のような表示を見るかもしれません。
FSF 版の emacs がシステムにインストールされている場合は、 C デバッガとの連携を連想させるような、Perl デバッガとの統合 ソフトウェア開発環境を提供します。
最近のバージョンの Emacs には emacs を Perl の文法(の一部)を解釈する文法指向の エディタとして振舞わせるためのスタートファイルを同梱しています。 perlfaq3 を参照してください。
ベンダー同梱の vi および X11 ウィンドウシステムと相互作用させるための Tom Christiansen による似たようなセットアップも利用可能です。 これは emacs が提供する統合マルチウィンドウサポートと同様に動作し、 デバッガがエディタを制御します。 しかし、これを記述している時点では、このツールの Perl 配布の中での 最終的な位置は不確定です。
vi ユーザーは、Perl のキーワードを色付けする、マウスとウィンドウ対応の vim と gvim を調べてみてください。
perl のみが完全に Perl をパースできるので、これら全ての CASE ツールには 足りないところがあることに注意してください; 特に C プログラマーが書くような Perl プログラムを書いていない場合はそうです。
Perl の実行に代替デバッガを使いたい場合は、-d オプションに コロンとパッケージからなる引数を付けてスクリプトを起動してください。 Perl 用代替デバッガは Perl プロファイラを含む Devel::DProf で、Perl 標準配布に含まれています。 ファイル mycode.pl にある Perl プログラムをプロファイリングしたい 場合、以下のようにします:
$ perl -d:DProf mycode.pl
スクリプトが終了すると、プロファイラはプロファイル情報を tmon.out というファイルにダンプします。 Perl 標準配布に含まれている dprofpp のようなツールが、この プロファイルの情報を解釈するのに使えます。 Devel::NYTProf
のような、より強力なプロファイラは CPAN から 利用可能です: 詳しくは perlperf を参照してください。
use re 'debug'
を指定すると、Perl 正規表現エンジンがどのように 動作するかの詳細を見ることができます。 この、典型的には大量の出力を理解するためには、 一般的に正規表現マッチがどのように行われるかだけでなく、 Perl の正規表現が内部的にどのようにオートマトンにコンパイルされるかを 知らなければなりません。 これらの事柄は詳細は "Debugging Regular Expressions" in perldebguts にあります。
Perl には自身のメモリ使用状況を報告するための内部機能があります。 しかしこれはかなり上級の概念で、メモリ割り当てがどのように行われるかに ついての理解が必要となります。 詳細については "Debugging Perl Memory Usage" in perldebguts を参照して下さい。
-w スイッチはもう使いましたよね?
perldebtut, perldebguts, re, DB, Devel::DProf, dprofpp, Dumpvalue, perlrun.
#! を使っているので普通は $PATH に見つかるスクリプトをデバッグするとき、 -S オプションを付けると perl は $PATH からスクリプトを探すので、 パスや which $scriptname
をタイプする必要がなくなります。
$ perl -Sd foo.pl
C や C++ 拡張のような、Perl でコンパイルされていないものに対して スタックフレーム情報やあらゆるデバッグ関数を使うことはできません。
サブルーチン内で(shift
や pop
を使って) @_ 引数を変更した場合、 スタックバックトレースで元の値を表示することはできません。
デバッガは現在のところ -W コマンドラインスイッチと同時に 使うことはできません。これ自身が警告から逃れられないからです。
(キーボードやソケットからの wait
, accept
, read
などの) 遅いシステムコールを実行中で、独自の $SIG{INT}
ハンドラを設定していない場合、 デバッガに戻ってくるために CTRL-C を使うことはできません。 これは、デバッガ自身の $SIG{INT}
ハンドラが 遅いシステムコールから longjmp(3) で出るための例外を発生させる必要性を 理解しないからです。