2011-06-19 2 views
16

Linuxでは、バックトレースを取得するためにbacktrace()ライブラリ呼び出しを使用できますが、現在のスレッドのバックトレースのみを返します。他のスレッドのバックトレースを取得する方法はありますか?私はそれがTID(またはpthread_t)であることを前提としています。他のスレッドのバックトレースを取得する

libunwind(http://www.nongnu.org/libunwind/)プロジェクトが役立つようです。問題は、CentOSがサポートしていないため、私はそれを使用しないことです。

他のアイデアはありますか?おかげさまで

答えて

7

バックトレースの助けを借りて信号処理を行うことで、目的を達成することができます。

スレッドのPIDがある場合、そのスレッドのシグナルを上げることができます。ハンドラではバックトレースを使用できます。ハンドラはその部分的なスレッドで実行されるので、バックトレースには必要なものが出力されます。

+1

これは私が探していたものではありませんが、これは良いアイデアです。私はそれを使うことができると思う。ありがとう! –

+0

@Alexanderは、mallocやfreeなどの呼び出しがコールスタックである場合に、この解決方法を提供します。この場合、シグナルハンドラからbacktrace()を呼び出すことができますか?私はクラッシュしています。 – sandeep

+0

最終的に、私はlibunwindで作業することにしました。この解決策は私の状況にとってはあまりにも複雑で、私はそれを断念することに決めました。とにかく、何とかしたら、ここに投稿してください。 –

8

私はそれ自身hereを実装しました。

最初は、hereと似たようなものを実装したいと思っていました。すなわち、何らかの方法でスレッドのトップフレームポインタを取得して手動で巻き戻しました。(リンク元はAppleのbacktraceの実装から派生しています。アイデアは一般的です)。

しかし、その安全を確保するには(とにかく上記のソースが壊れていなくても)、スタックにアクセスしている間はスレッドを一時停止する必要があります。スレッドを中断するさまざまな方法を探して、thisthis、およびthisが見つかりました。基本的に、本当に良い方法はありません。一般的なハックでもあるused by the Hotspot JAVA VMは、信号を使用してpthread_kill経由でスレッドにカスタム信号を送信することです。

とにかくこのようなシグナル・ハックが必要なので、少し単純にして、ターゲット・スレッド(here by sandeepも示唆)で実行されるシグナル・ハンドラ内でbacktraceを使用してください。これは基本的に私の実装がやっていることです。

有用なデバッグ情報(関数名、ソースコードファイル名、ソースコード行番号など)を取得するバックトレースの印刷に興味がある場合は、hereをlibbfdに基づいて拡張されたbacktrace_symbolsと読んでください。または、ソースhereをご覧ください。

+1

と呼んでいます。私は、バックグラウンドスレッドからメインスレッドの呼び出しスタックを取得する必要があるシナリオを持っています。 UIスレッドに2秒以上のハングがあると、200ミリ秒ごとにUIスレッドを監視するバックグラウンドスレッドがコールスタックを収集します。あなたのソリューションがこの問題にも対処してくれるのだろうかと思っていましたか事前に感謝します。 –

+0

@ilkerAcar:私の実装では、 'int GetCallstack(ThreadId threadId、void ** buffer、int size)'という関数はどのスレッドからでも呼び出すことができます。メインのスレッドIDを渡すだけです。 – Albert

+0

Btw。私はまた、いくつかのプロジェクトでこれをやっています。 'startMainLockDetector()' [here](https://github.com/albertz/openlierox/blob/0.59/src/MainLoop.cpp)を参照してください。 – Albert

0

GDBは、マルチスレッドプログラムをデバッグするために、これらの施設を提供しています。新しいスレッド

  • 'スレッドthread-ID'、スレッド
  • 「情報スレッドの間で切り替えるには、コマンドの

    • 自動通知を、既存のスレッドについて問い合わせるコマンド
    • 'thread apply [スレッドIDリスト] [すべて] args'、スレッドのリストにコマンドを適用するコマンド
    • スレッド固有のブレークポイント
    • スレッドの開始と終了時のメッセージの印刷を制御する 'set print thread-events'。
    • 'libthread-db-search-path path'を設定します。これにより、デフォルトの選択肢がプログラムと互換性がない場合に使用するlibthread_dbを指定することができます。

    GDBで必要なスレッドをcmd: 'thread thread-id'で実行してください。 スレッドのバックトレースを印刷するには、そのスレッドコンテキストで 'bt'を実行します。

  • 関連する問題