2008-12-24 87 views
7

如何在不使用dbghelp.dll的情況下獲取Windows上地址的堆棧跟蹤?如何在不使用dbghelp.dll的情況下在Windows上獲取堆棧跟蹤?

我不需要知道與地址相關的符號或函數名稱,我只想要地址列表 - 類似於backtrace of *nix systems

謝謝!

+0

你爲什麼要這樣做沒有DbgHelp.dll。從Windows 2000開始,DbgHelp.dll就是內置於Windows的。同時查看Jochen Kalmbach的Stackwalker:http://www.codeproject.com/KB/threads/StackWalker.aspx – Cheeso 2009-10-25 02:50:53

回答

9

查看CaptureStackBackTrace()函數,該函數位於Kernel32.dll中。這應該做你需要的一切。

通過走上堆棧並記錄每個幀的信息來捕獲堆棧返回跟蹤。

USHORT WINAPI CaptureStackBackTrace(
    __in  ULONG FramesToSkip, 
    __in  ULONG FramesToCapture, 
    __out  PVOID *BackTrace, 
    __out_opt PULONG BackTraceHash 
); 
+1

看起來不錯。但是我使用的是VS 2005,並且沒有在winbase.h中定義CaptureStackBackTrace no RtlCaptureBackTrace。 我會嘗試手動包括RtlCaptureBackTrace(...)的函數原型,看看它是否適用於我。謝謝! – Uhall 2008-12-24 23:47:15

+0

酷酷!我已經寫了3次堆棧跟蹤代碼,並不知道這存在。謝謝! – shoosh 2008-12-25 03:54:45

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]; 
    } 
} 
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]; 
} 
亞當,感謝突出的方式!

相關問題