3

私はプロジェクトに取り組んでおり、Javaアプリケーションのネイティブスタックを取得する必要があります。私はこれを部分的に達成することができます。ptrace/マルチプロセッシングとシグナルに感謝します。

Linuxでは、通常のJavaアプリケーションには最低14個のスレッドがあります。これらの14のうち、ネイティブスタックを取得する必要があるメインスレッドのみに関心があります。この目的を考慮して、メインスレッドのネイティブスタックを監視するfork()を使用して別のプロセスを開始しました。要するに、私には2つの別々のプロセスがあります。1つは監視されており、もう1つはptraceと信号処理を使用して監視を行います。

監視プロセスのステップ:

1)プロセスから他の14スレッドからメインスレッドIDを取得します。

2)ptrace_attach main_ID

3)ptrace_cont main_ID

連続ループ開始

{{

4)kill(main_ID、SIGSTOP)、

5)nanosleepと/ proc / [pid]/statディレクトリからのステータスの確認

6)スタックを読み取ってナビゲートするptrace_peekdata

7)ptrace_cont main_ID

8)nanosleepと/ proc / [pid]/statディレクトリからのステータスの確認

}

9)ptrace_detach main_ID

これにより、ネイティブスタック情報が継続的に完全に提供されます。しかし、時々私は1つの問題に直面します。

問題:

kill(main_ID、SIGSTOP)をメインスレッドに送信すると、プロセスの他のスレッドが終了または停止状態(T)になり、プロセス全体がブロックされます。これは一貫性のある動作ではなく、プロセス全体が正しく実行されます。メインスレッドに信号を送るだけなので、この動作を理解できませんでした。なぜ他のスレッドが影響を受けるのですか?誰かが問題の分析を手伝ってくれませんか?

また、プロセスのすべてのスレッドでCONTおよびSTOPシグナルを実行しようとしましたが、それでも問題が発生することがあります。

ありがとう、Sandeep

4

1 に答える 1

0

Linux を使用していると仮定すると、kill(2) の代わりに tkill(2) または tgkill(2) を使用する必要があります。FreeBSD では、SYS_thr_kill2 システムコールを使用する必要があります。tkill(2) マンページによると:

tgkill() は、スレッド グループ tgid 内のスレッド ID tid を持つスレッドにシグナル sig を送信します。(対照的に、kill(2) はプロセス (つまり、スレッドグループ) 全体にシグナルを送信するためにのみ使用でき、シグナルはそのプロセス内の任意のスレッドに配信されます。)

tkill(2) とその仲間が内部スレッド ライブラリを使用するためのものであることは無視してください。これは、特定のスレッドにシグナルを送信するためにデバッガ/トレーサーによって一般的に使用されます。

また、/proc/[pid]/stat をポーリングする代わりに、waitpid(2) (またはそのバリエーション) を使用して、スレッドが SIGSTOP を受信するのを待つ必要があります。このアプローチは、より効率的で応答性が高くなります。

最後に、ある種のスタック サンプリングを行っているようです。Google PerfToolsには、CPU 時間を最も消費している関数の推定値を取得するためにスタック サンプリングを行う CPU サンプラーが含まれているため、これらのツールを確認することをお勧めします。スタック サンプリングを堅牢にするのは難しいため、これらのツールが既に行った作業を再利用することもできます。

于 2011-11-01T04:28:26.033 に答える