2

たとえば、この情報を例外に追加するために、Windows で backtrace ユーティリティのアナログを実装したいと考えています。

リターン アドレスを取得し、それをシンボル名に変換する必要があります。

私は StackWalk64 とStackWalker プロジェクトを認識していますが、残念ながらいくつかの重要な欠点があります。

  • それは非常に遅いことが知られています (StackWalk64) トレースを収集するために多くの時間を無駄にしたくありません。基本的にはリンクされたリストを歩くのと同じくらい速く実行できます。
  • 関数 StackWalk64 は、スレッドセーフではないことが知られています。

x86 および可能な x86_64 アーキテクチャのみをサポートしたい

私が持っている基本的な考え方は次のとおりです。

  1. esp/ebp レジスタを使用して、スタックの一番下に到達するまで GCC の__builtin_return_address(x)/と同様にスタック上で実行し__builtin_frame_address(x)ます (これは glibc が行うことです)。
  2. アドレスをシンボルに変換する
  3. それらを分解します。

問題/質問:

  1. スタックの to に到達したことをどのように知ることができますか? たとえば、glibc の実装には次の機能が__libc_stack_endあるため、どこで停止するかを簡単に見つけることができます。Windowsの下でそのようなことの類似物はありますか? スタック ボトム アドレスを取得するにはどうすればよいですか?
  2. dladdr 機能の類似物は何ですか。これで、ほとんどのシンボル名を保持する ELF プラットフォームとは異なり、PE 形式は保持しないことがわかりました。したがって、何らかの形でデバッグ情報を読み取る必要があります。何か案は?
4

2 に答える 2

2
  • スタック トレースのキャプチャ: RtlCaptureStackBackTrace
  • シンボルの取得: DBG ヘルプ ライブラリを使用します (MSVC のみ)。主な機能:

    // Initialization
    hProcess = GetCurrentProcess()
    SymSetOptions(SYMOPT_DEFERRED_LOADS)
    SymInitialize(hProcess, NULL, TRUE)
    // Fetching symbol
    SymFromAddr(...)
    

    実装はそこにあります

于 2011-02-14T10:30:06.380 に答える
1

StackWalkシンボルを使用しますが、後で解決します。

于 2010-09-27T10:19:01.623 に答える