web-dev-qa-db-ja.com

プロセスが開始してアタッチするのを待つようにgdbに指示する方法はありますか?

別のプロセスによって呼び出されるプロセスがあり、別のプロセスによって呼び出されるなど、悪意があります。これは、長いツールチェーンの子プロセスです。

このプロセスはクラッシュしています。

このプロセスをgdbでキャッチして、クラッシュする理由を理解したいと思います。しかし、私が考えることができる唯一の方法は次のとおりです。

  1. コマンドラインで元の親プロセスを開始します。
  2. 投票ps -C <name process I want to catch>そしてPIDを取得します。
  3. そのプロセスのPIDにアタッチされたgdbを起動します。

これは面倒ですが、通常は仕事をします。問題は、現在の障害が非常に迅速に実行され、PIDをキャプチャしてgdbを起動するまでに、すでに障害ポイントを通過していることです。

Gdbを起動したいのですが、代わりに:

(gdb) attach <pid>

私がしたいのは:

(gdb) attach <process name when it launches>

これを行う方法はありますか?


Linuxでgdb7.1を使用しています

34
Nathan Fellman

これがgdbwaitと呼ばれる私のスクリプトです:

#!/bin/sh
progstr=$1
progpid=`pgrep -o $progstr`
while [ "$progpid" = "" ]; do
  progpid=`pgrep -o $progstr`
done
gdb -ex continue -p $progpid

使用法:

gdbwait my_program

確かにそれはもっとうまく書くことができますが、Bourne Shellスクリプトの構文は私にとって苦痛なので、それが機能する場合はそのままにしておきます。 :)新しいプロセスの起動と終了が速すぎる場合は、デバッグ用に独自のプログラムに1秒の遅延を追加してください...

24
fchen

Mac OS Xでは、次を使用できます。

(gdb) attach --waitfor <process-name>

ただし、これにより、非常に迅速に終了するプロセスをキャプチャできない場合もあります。これが他のプラットフォームでサポートされているかどうかはわかりません。

Mac OS X v10.5 WWDCシードのGDBリリースノート

8
Joey Hagedorn

親プロセスにアタッチして、follow-fork-mode childを設定できます。これにより、gdbは、フォーク後に親ではなく子プロセスをデバッグします。また、catch forkが役立ちます。これにより、各フォークの後にgdbが停止します。 docs を参照してください。

5
ks1322

期待どおりではありませんが、デバッグに役立つ場合があります。

valgrind --trace-children=yes your_program

プロセスのすべての子のメモリエラーをチェックして出力し、スタックトレースとエラーに関する詳細を示します(たとえば、ダブルフリーの場合、最初のフリーのスタックトレースを取得します)。

また、クラッシュプロセスでコアダンプを生成し、この事後デバッグを行うこともできます。 詳細はこの回答 を参照してください。

1
jpalecek

デバッグしようとしているもので同様の問題に直面していて、ldpreloadを使用して解決策を考え出しましたが、Joeysの回答を見た後、最初にそれを試してみると思います。ここにアイデアがありますが、それが他の誰かに役立つ場合に備えて:

LD_PRELOADライブラリを作成してexec *呼び出しをフックします(これを行う方法については多くのガイドがありますが、これを行う場合はコードで回答を更新します)、exec *呼び出しを通過するときに使用されるパスを確認します。それがターゲットの場合は、PIDを含むメッセージをstderrに出力し、無限ループに入ります(CPUの大量使用を避けるためにスリープを使用します)。次に、gdbを使用してアタッチし、ループで使用されるレジスタを変更して実行を続行できます。

これには、コンパイラが無限ループを最適化しないようにするためのインラインASMが含まれる場合があります。より雄弁な方法は、gdbがアタッチされたことを検出してブレークポイントをトリガーする方法を見つけることです( "asm(" int3 ");"は後者でトリックを実行する必要があります)。

1
PeterBelm