21

MONOで実行されるハングしているアプリケーションでスレッド(スタックトレース)を表示するにはどうすればよいですか?

.NETでManagedStackExplorer(MSE)を使用してそれを実行できることを知っています。アプリケーションはMONOでのみハングするため、MONOで実行する必要があります。

または、ぶら下がっている場所を見つける方法は他にありますか?

4

2 に答える 2

25

WindowsではなくLinux/Unixを使用していると仮定して、プログラムにSIGQUITシグナルを送信します。これはで行うことができます

kill -QUIT $PID

ここで、$PIDはプログラムのpidです。その後、Monoはすべてのスレッドのスタックトレースをstdoutにダンプします。この後もプロセスは実行されたままですが、使用可能/安定したままであると期待するべきではないことに注意してください。

背景については、http://en.wikipedia.org/wiki/SIGQUITを参照してください。

注:スレッドダンプは、コマンドを実行したターミナルウィンドウには出力されません。killモノプロセスのstderrに表示されます。

于 2010-01-15T00:04:24.940 に答える
2

GDBを使用してマネージドスタックトレースをすばやく取得することもできます。実行gdb; ユーザーが所有するプロセスをroot化またはデバッグしていない場合は、sudoを使用してください。

mono-project.orgのMonoページのデバッグから取得した次のスクリプトを実行します。

handle SIGXCPU SIG33 SIG35 SIGPWR nostop noprint

define mono_stack
 set $mono_thread = mono_thread_current ()
 if ($mono_thread == 0x00)
   printf "No mono thread associated with this thread\n"
 else
   set $ucp = malloc (sizeof (ucontext_t))
   call (void) getcontext ($ucp)
   call (void) mono_print_thread_dump ($ucp)
   call (void) free ($ucp)
 end
end

必要に応じて、これらのコマンドをにドロップして~/.gdbinit、常にコピーして貼り付ける必要がないようにすることができます。

次に、PIDに添付します。

attach 12345

プロセス全体が一時停止されていることに注意してください。本番環境でこれを行う場合は、できるだけ高速になるようにスクリプトを作成することをお勧めします。

スタックトレースを取得するには、mono_stack上記の定義に従って実行します。gdbではなくstdoutに出力が表示されることに注意してください。upstartを使用してプロセスを実行する場合は、upstartジョブを編集して、console logにログインするために使用できます/var/log/upstart

ただし、メインスレッド以外のスレッドに興味があるかもしれません。これを行うには、実行info threadsしてスレッドリストを取得thread 2し、スレッド#2に切り替えます。スレッドのデバッグの詳細については、GDBドキュメントの複数のスレッドを使用したプログラムのデバッグを参照してください。

完了したら、を実行するquitと、プログラムは引き続き機能します。

于 2016-08-31T12:31:22.807 に答える