3

ベンダー提供のライブラリをステップスルーすると、呼び出しがAUTOLOAD実行され、コードリファレンスが によってキャプチャされ、UNIVERSAL::can()そのコードリファレンスが呼び出されます。呼び出しは、DynaLoader を介してコンパイルされたライブラリからのルーチンに対するものだと思います。

問題は、この行に到達したときに$result = &$coderef(@args)、デバッガーが coderef にステップインせず、モジュール自体の次の行に移動することです。しかし、私は警告Use of uninitialized value in string ne at (eval 1) line 1670されており、coderef は単なる外部ライブラリの呼び出し以上のものであると考えています。

私はs $coderef->(@args)手で試してみましたが、それに「ステップイン」しましたが、同じ警告であり、通話との他のやり取りはありません。

これがラッパーであることを証明する方法はありますか?デバッガーにその内部を強制的に表示させることさえできますか?

より多くのコード コンテキストを編集します (CQPerlExt.pm、IBM ClearQuest Perl API から大幅に削除されたルーチン):

sub AUTOLOAD {
    my @args = @_;
    (my $sub = $AUTOLOAD) =~ s/::/_/g;
    my $coderef = UNIVERSAL::can(__PACKAGE__."c", $sub)
        or Carp::croak "Undefined subroutine &$AUTOLOAD called";

    my $result = &$coderef(@args);
    return $result;
}

それは機能し、意図したルーチンは想定どおりに動作しますが、7 行目が実行されると警告が表示されます。デバッガーの手順は 8 行目まで続きます。

外部ライブラリのブートストラップである CQPerlExtc パッケージがあります。

この場合、@args には、ClearQuest の「エンティティ」オブジェクトへの参照と文字列「変更」が含まれます (どちらもこの呼び出しに適しています)。

4

1 に答える 1

0

これを行う最善の方法は、単純に C でテスト プログラムを作成し、Perl で実行しようとしていることをシミュレートすることです。DynaLoader を介して実行されている C コードをデバッグするためのより良い方法があればいいのにと思いますが、今のところ見たことがありません。また、Perl デバッガーのポケット リファレンスをクラックしましたが、DynaLoader についての言及は見当たりません。

これをデバッガーに取り込み、C 関数に渡される値を C プログラムにコピーしてから、gdb を実行します。

于 2013-08-23T18:31:03.143 に答える