14

私は通常、1 つまたは 2 つのプロジェクトで gdb を使用しています。つまり、私は呼び出しgdb --args prog argsます。gdb は、デバッグ中のプログラムと同じ tty で実行されます。

ただし、私の最新のプロジェクトは dtach ユーティリティを変更しています。これは画面のようなプログラムなので、tty は別の場所にリダイレクトされるため、gdb のアタッチ機能を使用する必要があります。

gdb attach の問題は、アタッチする pid を取得するために最初にプログラムを実行する必要があるため、明らかに最初からアタッチできないことです。

gdb がアタッチされるまで、ある時点でプログラムを待機させる方法はありますか?

cygwin を使用しているため、gdbserver を使用できません。また、 を使用してpause()みましたが、続行しようとするとハングしました。

4

3 に答える 3

15

これが私がこの問題を解決する方法です。他の人もこのトリックをしているのを見たことがあります。

プログラムを停止する場所を選択し、デバッガーがアタッチされるのを待ちます。ほとんどのプログラムでは、これが最初の作業になりますが、必要な初期化作業がある場合は、それを終了してからこれを実行することをお勧めします。

次のようなループを挿入します。

#ifdef DEBUG

int i = 0;

while (i == 0)
{
    usleep(100000);  // sleep for 0.1 seconds
}

#endif // DEBUG

プロセスへのアタッチが正常に完了したら、デバッガーを使用して変数の値を変更できますi。これにより、ループが中断され、通常の実行が続行されます。

変数を 1 に変更する gdb コマンド:set var i = 1

私が常に行っているもう 1 つのことは、nop()何もしない (「操作なし」) という短い関数を定義することです。次に、中断したい場所への呼び出しに固執し、nop()内部にブレークポイントを置きますnop()

注: デバッグ ビルドをビルドする-O0場合、コンパイラは変数を最適化しません。最適化されたビルドでこのトリックが必要な場合は、変数を として宣言する必要があると思いますvolatile

于 2012-06-29T03:05:22.157 に答える
1

一部のプラットフォームには、デバッガー待ち命令またはトラップがある場合があります。

移植性を高めるには、ソケットへの接続や fifo へのデータの書き込みなど、外部的に満たされた条件でプログラムを待機させることができます。その後、接続を確立するか、3 番目の端末からダミー データを送信できます。

または、プログラムに無限ループを配置して、続行できるようにするためにデバッガーで変更する揮発性変数の値をテストすることもできます。

思い出すと、cygwin プログラムで Windows API を使用できます。一部の Web 検索では、プログラムがデバッグされているかどうかを検出するための API が示されているようです。そのため、それが戻るまでループできる可能性があります。

于 2012-06-29T02:55:09.833 に答える