別のプロセスによって呼び出されるプロセスがあり、別のプロセスによって呼び出されるなど、悪意があります。これは、長いツールチェーンの子プロセスです。
このプロセスはクラッシュしています。
このプロセスをgdbでキャッチして、クラッシュする理由を理解したいと思います。しかし、私が考えることができる唯一の方法は次のとおりです。
ps -C <name process I want to catch>
そしてPIDを取得します。これは面倒ですが、通常は仕事をします。問題は、現在の障害が非常に迅速に実行され、PIDをキャプチャしてgdbを起動するまでに、すでに障害ポイントを通過していることです。
Gdbを起動したいのですが、代わりに:
(gdb) attach <pid>
私がしたいのは:
(gdb) attach <process name when it launches>
これを行う方法はありますか?
Linuxでgdb7.1を使用しています
これが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秒の遅延を追加してください...
Mac OS Xでは、次を使用できます。
(gdb) attach --waitfor <process-name>
ただし、これにより、非常に迅速に終了するプロセスをキャプチャできない場合もあります。これが他のプラットフォームでサポートされているかどうかはわかりません。
親プロセスにアタッチして、follow-fork-mode childを設定できます。これにより、gdbは、フォーク後に親ではなく子プロセスをデバッグします。また、catch forkが役立ちます。これにより、各フォークの後にgdbが停止します。 docs を参照してください。
期待どおりではありませんが、デバッグに役立つ場合があります。
valgrind --trace-children=yes your_program
プロセスのすべての子のメモリエラーをチェックして出力し、スタックトレースとエラーに関する詳細を示します(たとえば、ダブルフリーの場合、最初のフリーのスタックトレースを取得します)。
また、クラッシュプロセスでコアダンプを生成し、この事後デバッグを行うこともできます。 詳細はこの回答 を参照してください。
デバッグしようとしているもので同様の問題に直面していて、ldpreloadを使用して解決策を考え出しましたが、Joeysの回答を見た後、最初にそれを試してみると思います。ここにアイデアがありますが、それが他の誰かに役立つ場合に備えて:
LD_PRELOADライブラリを作成してexec *呼び出しをフックします(これを行う方法については多くのガイドがありますが、これを行う場合はコードで回答を更新します)、exec *呼び出しを通過するときに使用されるパスを確認します。それがターゲットの場合は、PIDを含むメッセージをstderrに出力し、無限ループに入ります(CPUの大量使用を避けるためにスリープを使用します)。次に、gdbを使用してアタッチし、ループで使用されるレジスタを変更して実行を続行できます。
これには、コンパイラが無限ループを最適化しないようにするためのインラインASMが含まれる場合があります。より雄弁な方法は、gdbがアタッチされたことを検出してブレークポイントをトリガーする方法を見つけることです( "asm(" int3 ");"は後者でトリックを実行する必要があります)。