2009-09-21 6 views
35

の2つのプログラムblahretがあります。私はblahをデバッグしたいと思います。retからの入力をI/Oリダイレクション経由で受け取るプログラムです。次の場合、gdbを使用してblahプログラムをデバッグするにはどうすればよいですか?gdb - パイプによるデバッグ

bash> ret | blah 
+0

これは次のものとは異なりますか。http://stackoverflow.com/questions/4521015/how-to-pass-arguments-and-redirect-stdin-from-a-file-to-program-run-in-gdb –

答えて

41

まず、プログラムを実行してpidでデバッグすることができます。もちろん、このソリューションはすべてのケースをカバーしているわけではありません。

もう1つのアプローチは、プロセス間通信にLinux機能を使用することです。要するに、retの出力をFIFO特殊ファイル( "名前付きパイプ")にリダイレクトし、そのFIFOからデバッガ経由で読み込みます。ここでそれがどのように行われます。 bashのことから、次のコマンドを実行します

mkfifo foo 

これは名前付きパイプとして機能するディレクトリに特別なファイルを作成します。このファイルに(同じ構文echo "Hello" >fooを使用して)テキストを書き込むと、誰かがファイルからデータを読み取るまで書き込みプログラムがブロックされます(cat <fooなど)。私たちの場合、gdb制御プロセスはこのファイルから読み込みます。あなたはbashのから実行するFIFOを作成した後

ret > foo & # ampersand because it may block as nobody is reading from foo 
gdb blah 

次に、GDBプロンプトで、

run <foo 

を実行して、所望の効果を得ます。 FIFOのデータを通常のパイプと同じように2回読み取ることはできません。すべてのデータを読み終えたら、blahプロセスが終了し、fooへのコマンド書き込みを繰り返す必要があります。他のシェルウィンドウから)。

完了したらrm fooでfifoを削除します(または、システム再起動時に自動的に削除されるディレクトリに配置します(/tmpなど)。

+1

あなたがディスクスペースを確保することができれば、FIFO 'foo'ではなく、通常のファイル' foo'にパイプすることもできます。 – Frank

+7

通常のファイルとFIFO /パイプは、read()のセマンティクスが異なります。通常のファイルでEOFに達した場合、read()は指定されたバイト数よりも少ないバイト数で返されます。 FIFO /パイプから読み込むと、指定されたバイト数が到着するか、パイプへの書き込み処理が終了するまでread()ブロックがブロックされます。 – SzG

9

GDBのrunコマンドは、リダイレクトを実行するためにbashを使用します。 ret | blahに相当する簡単な方法は、bashのprocess substitution機能を使用することです。

$ gdb blah 
... 
(gdb) run < <(ret) 

説明:bashがretの標準出力のファイルディスクリプタである/dev/fd/123のようなもの、と<(ret)置き換えます。私たちは手動でそれ自身を作成する必要はなく、retプロセスの寿命について心配することを除いて、他の答えに記載されているように、そのfdを名前付きFIFOと同様に使用できます。

+0

私のニーズにちょうど合う、ありがとう。 – Limeth

+0

これはzshでは機能しません。代わりがありますか? – redfast00

+0

プロセス置換は、bashと同じようにzshで機能します。あなたの呼び出しは何ですか?どのようなエラーメッセージが表示されますか? –

関連する問題