2008-12-24 91 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]; 
} 
亚当,感谢突出的方式!

相关问题