デバッグしようとしている Perl (Linux 環境) のかなり複雑なプログラムに問題があります。ここの簡単なスニペットで問題をシミュレートできます ( test.pl
):
use warnings;
use strict;
use feature qw/say/;
my @testa = ();
my $numelems = 10000;
# populate array/list of arrays
for (my $ix = 0; $ix < $numelems; $ix++) {
my @miniarr = ($ix, 1);
push(@testa, \@miniarr);
}
say "Array is now " . scalar(@testa) . " elements long";
my $BADnumelems = $numelems + 2;
my $sum = 0;
# loop through array/list of arrays
for (my $ix = 0; $ix < $BADnumelems; $ix++) {
my @minientry = @{$testa[$ix]};
$sum += $minientry[0];
}
say "Sum of elements is $sum";
このプログラムを実行すると、次のように終了します。
$ perl test.pl
Array is now 10000 elements long
Can't use an undefined value as an ARRAY reference at test.pl line 22.
だから、今私はそれをデバッグしたいと思います-しかし、エラーによりプログラムが終了し、デバッガーが終了します:
$ perl -d test.pl
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(test.pl:6): my @testa = ();
DB<1> c
Array is now 10000 elements long
Can't use an undefined value as an ARRAY reference at test.pl line 22.
at test.pl line 22
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
DB<1> p $sum
DB<2> exit
$
次に、デバッガー (PerlMonks) でブレーク オン ワーニングを見つけました。だから私はこれを追加しようとしました:
...
use feature qw/say/;
$SIG{__DIE__} = sub { my($signal) = @_; say "DIEhandler: $signal"; $DB::single = 1; };
$SIG{__WARN__} = sub { my($signal) = @_; say "WARNhandler: $signal"; $DB::single = 1; };
my @testa = ();
...
...しかし、これもデバッガーを殺します:
$ perl -d test.pl
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(test.pl:6): $SIG{__DIE__} = sub { my($signal) = @_; say "DIEhandler: $signal"; $DB::single = 1; };
DB<1> c
Array is now 10000 elements long
DIEhandler: Can't use an undefined value as an ARRAY reference at test.pl line 25.
Can't use an undefined value as an ARRAY reference at test.pl line 25.
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
さて、問題は、Ctrl-C でプログラムを中断すると、通常、デバッガーがステップ モードに入るということです。たとえば、 を設定my $numelems = 100000000;
し、ループ中に Ctrl-C を押すと、次のようにデバッグできます。
$ perl -d test.pl
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(test.pl:6): $SIG{__DIE__} = sub { my($signal) = @_; say "DIEhandler: $signal"; $DB::single = 1; };
DB<1> c
^Cmain::(test.pl:14): my @miniarr = ($ix, 1);
DB<1> p $ix
148607
DB<2> q
これで、ソース perl プログラムにブレーク ポイントを挿入できます。
...
for (my $ix = 0; $ix < $BADnumelems; $ix++) {
$DB::single = 1; ### <=== BREAK HERE
my @minientry = @{$testa[$ix]};
...
しかし、次の場合にループに入ります$ix = 0
。
$ perl -d test.pl
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(test.pl:6): $SIG{__DIE__} = sub { my($signal) = @_; say "DIEhandler: $signal"; $DB::single = 1; };
DB<1> c
Array is now 10000 elements long
main::(test.pl:26): my @minientry = @{$testa[$ix]};
DB<1> p $ix
0
DB<2> q
...そして、問題のある部分に到達するために 10000 個の要素をステップスルーしたくありません:)
それで、私は次のように考えました-Perlスクリプト自体からSIGINT(Ctrl-C)を発生/生成/作成する方法があれば、ダイハンドラーからそれを発生させ、できればステップインを引き起こすことができますプロセスが終了する前にデバッガー。だから、私の質問は次のとおりです。
- Perl スクリプトから SIGINT を上げることは可能ですか?
- 前のことが可能である場合、プロセスが終了する前に、ダイ ハンドラから Ctrl-C を使用してデバッガ ステップ モードに入ることができますか?
- 前のことが不可能
die
な場合 - プログラムs の行で、デバッガーのステップ モードに入る必要がある可能性はありますか?