7

Windows で dbghelp.dll を使用せずにアドレスのスタック トレースを取得するにはどうすればよいですか?

アドレスに関連付けられているシンボルや関数名を知る必要はありません。アドレスのリストが必要なだけです。これは、*nix システムのバックトレースに似たものです。

ありがとう!

4

3 に答える 3

9

Kernel32.dll にあるCaptureStackBackTrace()関数を確認してください。これで、必要なすべてが実行されるはずです。

スタックをたどって各フレームの情報を記録することにより、スタック バック トレースをキャプチャします。

USHORT WINAPI CaptureStackBackTrace(
  __in       ULONG FramesToSkip,
  __in       ULONG FramesToCapture,
  __out      PVOID *BackTrace,
  __out_opt  PULONG BackTraceHash
);
于 2008-12-24T23:42:07.797 に答える
2

これを非常に移植性の低い方法で行いたい場合は、EBP レジスタを読み取って自分でスタックを調べることができます。これは x86 アーキテクチャでのみ機能し、使用している C ランタイムが最初の関数を呼び出す前に EBP を 0 に適切に初期化することも前提としています。

uint32_t read_ebp(void)
{
    uint32_t my_ebp;
    __asm
    {
        mov ebp, my_ebp
    }

    return my_ebp;
}

void backtrace(void)
{
    uint32_t ebp = read_ebp();

    printf("backtrace:\n");

    while(ebp != 0)
    {
        printf("0x%08x\n", ebp);
        ebp = ((uint32_t *)ebp)[1];
    }
}
于 2008-12-25T00:30:57.977 に答える
1

以前のバリアントは私(msvc 6)では機能しないため、次のようになります。

unsigned long prev;
unsigned long addr;
__asm { mov prev, ebp }
while(addr!=0) { 
  addr = ((unsigned long *)prev)[1]; 
  printf("0x%08x\n", addr); 
  prev = ((unsigned long *)prev)[0]; 
}
アダム、道を強調してくれてありがとう!

于 2009-03-19T17:54:51.977 に答える