アプリケーションの共有オブジェクトから「addr2line」をフォークしてスタックトレースを構築します。どのくらい安全ですか?

アプリケーションの共有オブジェクトから「addr2line」をフォークしてスタックトレースを構築します。どのくらい安全ですか?

私は、プロセスやスレッドがターミナル信号(SIGSEGV、SIGABRTなど)を受信したときにトレースをエクスポートするようにLinuxで実行されるアプリケーションを強化しています。

backtrace(3)コードはbacktrace_symbols(3)、を使用してうまく機能し、バックトレースdladdr(3)abi::__cxa_demangle役立つ情報を生成します。

addr2lineそれ以外にも、ソースファイル名と行番号を生成しようとしたときに提供されたアドレスを使用して実行可能ファイルを送信するとうまく機能することがわかりましたが、最近は共有オブジェクト内にシンボルがある限りbacktrace(3)生成するのは簡単です??:0backtrace友達が報告した住所がASLRの影響を受けたようです。この問題は私のスタックトレースの大部分(すべてではありません)に影響を与え、現在のフォーキングの価値を減らしていますaddr2line

問題を解決し、ファイルと行番号を取得する方法に関するインターネットの結果がまれになり始めました。しかし、私は最近、次の問題を解決するためにメモリマッピングがどのように機能するかを十分に学びました。

  • backtrace_symbols(3)共有オブジェクトにこのアドレスとオフセットを追加して送信するときに、指定されたシンボルを見つけるためにこの共有オブジェクトで使用できる共有オブジェクトへのパスを含む文字列を指定しますdladdr(3)。ファイルと行番号が正しく生成されました。dli_fnamenmbacktrace_symbolsaddr2line -e <sharedobjectpath>
  • /proc/<pid>/maps共有オブジェクトパスでマッピングされたアドレスを検索し、報告されたアドレスからその値を減算すると、上記の共有オブジェクトr-xpbacktrace(3)まったく同じアドレスを取得できます。
  • 共有オブジェクトマップアドレスを直接取得すると(まだテストしていませんが直感的に)、dladdr1(3)アクセスをスキップできます/proc/<pid>/maps

addr2lineとにかく、ここではファイルと行番号を取得するために分岐する必要があるようです。これは少し痛みがあり(数百ミリ秒かかります)、libbfd私のアプリケーションに依存関係を導入せずに必要なようです。

修正する:詳しくは見ていないが、 で見つけたアドレスが の/proc/<pid>/maps値と同じであることがわかりました。それはすべてです。まったく上を見る必要はありません。dli_fbasedladdr(3)/proc/<pid>/maps

これを行うよりクリーンで直接的な方法はありますか? 3番目の箇条書きのためaddr2line。 (編集する:住所を教えてもらえますか?私の言及は無視してください/proc/<pid>/maps。 )2番目の箇条書きはすでに必要なフォークを取得するために読み取ることができることを示して/proc/<pid>/mapsaddr2lineます 3番目の箇条書きは実行不可能であることがわかります)私のプログラムからのアクセスに関連するセキュリティ/アクセス/セキュリティの問題はあります/proc/<pid>/mapsか?ランニングはどうですかaddr2line

答え1

わかりました、これは非常に遅い答えですが、とにかく役に立ちます。最近addr2line同じ問題を解決していますが、使用を避けたい場合ライブラリファイル。また、一部プロジェクトあなたのためにこれを行います(まだ直接テストする機会がありませんでした)。

関連情報