2012-05-04 7 views
3

共有ライブラリ内でSEGSEGVを取得した後、スタックトレースを取得してファイルに保存しようとしています。共有ライブラリは、クローズドソース製品用のプラグインです。これらはすべて本番環境で動作し、私はそれに直接アクセスすることはできません。共有ライブラリ内のバックトレース機能

私のコードはSIGSEGVシグナルをキャッチし、スタックトレースを出力して終了します。

[0x2aecc2019f11] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] は/ opt/ecelerity/libexecに/opt/ecelerity/libexec/site/ec_attachextensions.so:私はこのような何かを持っています【0x2aecc201a587]

/OPT/ecelerity/sbinに/ ecelerity [0x5]

/OPT/ecelerity/sbinに/opt/ecelerity/libexec/site/ec_attachextensions.so /site/ec_attachextensions.so [0x2aecc2019fee] /ecelerity(sieve_seng_execute + 0x82)[0x506d32] /opt/ecelerity/libexec/validate/sieve.so [ 0x2aecc2862c9e] /OPT/ecelerity/sbinに/ ecelerity(VALIDATE_DATA + 0xA5の)0x4a90d5] /OPT/ecelerity/sbinに/ ecelerity(esmtp_message_factory + 0x154e)0x46eace] /OPT/ecelerity/sbinに/ ecelerity(schedule_event_and_dispatch + 0x6a) [0x49c59a]

問題は、共有された ライブラリでは、関数名とオフセットの名前を持つことができないということです。私が理解するように、/proc/$PID/mapsにライブラリオフセットが見つかると、 addr2lineユーティリティの助けを借りて、指定されたアドレスの関数名/ファイル名を見つけることができます。

その後、私はそのような何かを実行しています:

0x2aecc2019f11は、上記のスタックトレースからのアドレスである
addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11) 

。私はマップファイルに触れることなくスタックトレースで関数名を得ることができる方法があるのだろうか?言い換えれば、私はどのようにプログラムすることができますか? dladdrこちら(dladdr私の場合はbacktraceが提供するアドレスから関数名を取得できません)

答えて

1

バックトレースコードは、関数名を決定するためにdladdrとほぼ同じメカニズムを使用します。

リンカーマップファイル(エクスポートされるものを定義し、他のすべてのアイテムの表示を制限するために使用できる)または明示的な可視シンボルを持つ-fvisibility=hiddenを使用してライブラリを構築する場合、バックトレース出力には表示されません。

回避策は、ライブラリ内のすべてのシンボルの可視性を制限するマップファイルを使用せずにコンパイルするか、-fvisibility=defaultでビルドすることです。それはあなたのために何の努力もせずに働くためにバックトレースを取得します。

これを実行せずに動作させるには、.soからローカルシンボルテーブルをロードし、addr2lineと同様のメカニズムを使用してシンボルの位置を決定する必要があります。これを行うメカニズムはlibelf1を使用することです。ローカルのシンボルテーブルを読み込みます。

...もちろん、テーブルからファイルが削除されていないことが必要です。そうであれば、.soは単に情報を持ってこないので、これらの罠は重要ではありません。

1

シグナルハンドラに/ proc/self/mapsを読み込ませることができます。

または、関数の絶対アドレスを出力して、比較ポイントとして使用してライブラリオフセットを見つけることができます。

しかし、あなたがベースアドレスを与えるダイナミックなリンカ機能があれば、私は驚くことはありません。ドキュメントをチェックすることができます。

関連する問題