19

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

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

他のアイデアはありますか?ありがとう。

4

3 に答える 3

11

私はここでそれを自分で実装しました。

最初は、ここで提案されているようなものを実装したかったのです。つまり、スレッドのトップフレームポインタを取得して手動で巻き戻しました(リンクされたソースはApplebacktraceの実装から派生しているため、Apple固有の可能性がありますが、考え方は一般的です)。

ただし、その安全性を確保するには(そして、上記のソースは壊れている可能性があり、とにかく壊れている可能性もあります)、スタックにアクセスしている間、スレッドを一時停止する必要があります。スレッドを一時停止するさまざまな方法を探し回って、これ、これこれを見つけました。基本的に、本当に良い方法はありません。Hotspot JAVA VMでも使用される一般的なハックは、シグナルを使用し、 pthread_killを介してカスタムシグナルをスレッドに送信することです。

したがって、とにかくそのようなシグナルハックが必要になるので、少し単純にbacktraceして、ターゲットスレッドで実行される呼び出されたシグナルハンドラー内で使用することができます(ここでもsandeepによって提案されています)。これは基本的に私の実装が行っていることです。

バックトレースの印刷にも関心がある場合、つまり、有用なデバッグ情報(関数名、ソースコードファイル名、ソースコード行番号など)を取得する場合は、libbfdに基づく拡張についてここをお読みください。または、こちらbacktrace_symbolsのソースをご覧ください。

于 2012-04-06T22:29:02.817 に答える
9

バックトレースの助けを借りた信号処理はあなたの目的を解決することができます。

つまり、スレッドのPIDがある場合は、そのスレッドのシグナルを生成できます。ハンドラーでは、バックトレースを使用できます。ハンドラーはその特定のスレッドで実行されるため、バックトレースには必要な出力があります。

于 2011-06-20T06:44:07.373 に答える
1

gdbは、マルチスレッドプログラムをデバッグするための次の機能を提供します。

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

したがって、cmdによってGDBの必要なスレッドに移動するだけです:'threadthread-id'。次に、そのスレッドコンテキストで「bt」を実行して、スレッドのバックトレースを出力します。

于 2016-11-03T06:57:37.360 に答える