8

カスタムLinuxディストリビューションでpthreadをデバッグしたいのですが、何かが足りません。私のホストはUbuntu12.04で、ターゲットはcrosstool-NGクロスコンパイラツールセットで構築されたi486カスタム組み込みLinuxであり、残りのOSはBuildrootで作成されています。

私は事実をリストします:

  • ターゲットでマルチスレッドアプリケーションを実行できます

  • ターゲットでマルチスレッドアプリケーションを実行すると、GoogleBreakpadがクラッシュレポートを作成できません。まったく同じビルドのBreakpadライブラリを備えたまったく同じアプリケーションは、ホストで実行すると成功します。

  • GDBは、ターゲット上のマルチスレッドアプリケーションのデバッグに失敗します。

例えば

$./gdb -n -ex "thread apply all backtrace" ./a.out --pid 716

dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.
GNU gdb 6.8

このため、ps_lgetfpregsは問題ではないと思います。

  • crosstoolビルドでlibthread_db.soファイルが作成され、ターゲットに配置されました。

  • crosstoolビルドはターゲットのgdbを作成したので、ターゲットで実行しているのと同じライブラリに対してリンクされている必要があります。

  • ホストでテストアプリに対してgdbを実行すると、実行中の各スレッドのバックトレースが取得されます。

Breakpadの問題はGDBの問題に関連していると思いますが、これを実証することはできません。唯一の共通点は、マルチスレッドデバッグの欠如です。

ホストとターゲットの間にはいくつかの重大な違いがあり、ターゲットでpthreadをデバッグできなくなります。

誰かがそれが何であるか知っていますか?

編集:

TIのDenysDmytriyenkoは次のように述べています。

通常、GDBはそれほど扱いにくいものではなく、異なるバージョンのgdbとgdbserverを組み合わせて使用​​できます。ただし、残念ながら、マルチスレッドアプリをデバッグする必要がある場合は、特定のAPIにいくつかの依存関係があります...

たとえば、これは、スレッドサポート用にGDBを適切にビルドしなかった場合に表示される可能性のあるメッセージの1つです。

dlopenが'libthread_db.so.1'で失敗しました-/lib/libthread_db.so.1:未定義のシンボル:ps_lgetfpregsGDBはpthreadをデバッグできません。

このエラーは私が得たものと同じですが、彼はGDBを「適切に」構築する方法について詳しく説明していないことに注意してください。

GDBのFAQには次のように書かれています。

(Q)GDBは、クラッシュが発生したスレッド以外のスレッドを認識しません。または、ブレークポイントを設定すると、SIGTRAPがプログラムを強制終了します。

(A)これは、Linux、特に組み込みターゲットで頻繁に発生します。2つの一般的な原因があります。

  • glibcを使用していて、libpthread.so.0を削除しました

  • libpthread.so.0とlibthread_db.so.1の不一致

GDB自体は、glibcによって維持され、glibcのプライベート実装の詳細と見なされる「スレッド制御ブロック」をデコードする方法を知りません。libthread_db.so.1(glibcの一部)を使用してこれを支援します。したがって、libthread_db.so.1とlibpthread.so.0は、バージョンフラグとコンパイルフラグが一致している必要があります。さらに、libthread_db.so.1では、libpthread.so.0に特定の非グローバルシンボルが存在する必要があります。

解決策:striplibpthread.so.0の代わりにstrip--strip-debuglibpthread.so.0を使用してください。

ストリップされていないlibpthread.so.0を試しましたが、違いはありませんでした。pthreadとthread_dbの不一致を調査します。

4

2 に答える 2

5

これ:

dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.

ライブラリがgdblibthread_db.so.1でシンボルを見つけることができなかったことを意味します。ps_lgetfpregs

なんで?

Crosstoolg-NGを使用して「静的ネイティブgdbをビルドする」オプションを指定してgdbをビルドしたため、これにより-staticオプションがgccに追加されます。

ネイティブgdbは-rdynamicオプションを使用して構築され、これにより、ELFファイルの.dynsymシンボルテーブルに、未使用のシンボルを含むすべてのシンボルが入力されます。libread_dbは、このシンボルテーブルを使用してps_lgetfpregsgdbから検索します。

ただし、 -staticELF.dynsymファイルからテーブルを削除します。

この時点で、2つのオプションがあります。

  1. スレッドをデバッグする場合は、静的なネイティブgdbをビルドしないでください。
  2. 静的gdbと静的libthread_dbをビルドします(テストされていません)

編集:

ちなみに、これは、Breakpadがターゲット上のマルチスレッドアプリケーションをデバッグできない理由を説明していません。

于 2012-09-11T08:04:06.010 に答える
0

ただし...gdbデバッガーを使用するには、-gオプションを使用してコードをコンパイルする必要があります。たとえば、gcc -g -c*.cです。

于 2013-10-14T18:35:49.480 に答える