2009-12-04 53 views
0

我试图在收到SIGSEGV时使用DbgHelp.dll中的StackWalk64函数获取堆栈跟踪,但获取的堆栈跟踪与访问的实际站点无关违反:在Windows上访问冲突后获取堆栈跟踪

[0] sigsegv_handler() e:\hudson\jobs\ide-nightly-trunk\workspace\ide-nightly-trunk\core\ide\cspyserver\src\stackwalker\cssstackwalker.cpp:31 
[1] XcptFilter() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
[2] __tmainCRTStartup() f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:603 
[3] seh_longjmp_unwind4() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
[4] BaseThreadInitThunk() C:\Windows\syswow64\kernel32.dll 
[5] RtlCreateUserProcess() C:\Windows\SysWOW64\ntdll.dll 
[6] RtlCreateProcessParameters() C:\Windows\SysWOW64\ntdll.dll 

我怀疑怪异的窗口异常处理和setjmp/longjmp的参与,但我真的不知道我应该寻找。

回答

2

请注意,在访问冲突之后获得可靠的堆栈错误总是很有挑战性。根据定义,当AV发生时该过程是损坏的,因此可能无法检索到实际的堆栈跟踪后缀(例如,如果导致异常的错误也破坏了您的堆栈行走逻辑所使用的某些结构会发生什么情况)?

在这种情况下,您似乎试图捕获异常过滤器中的堆栈跟踪,该异常过滤器将无法工作 - 异常过滤器在部分展开的堆栈上运行。你可以找到异常记录和与GetExceptionInformation API失败的背景记录(所以你需要做的是这样

__try 
    { 
    <stuff> 
    } 
    __except(MyExceptionFilter(GetExceptionInformation()) 
    { 
    <stuff> 
    } 

你应该能够获取准确的堆栈跟踪这个API只能从过滤器表达式工作与上下文记录和例外信息

+0

是的,我知道我没有任何保证,我可以得到一个完整的堆栈跟踪,但这是关于获取尽可能多的信息,当系统崩溃,所以部分或破碎stacktrace总比没有好。 – JesperE

0

我在Windows上没有任何使用C运行时支持的经验。但是,使用向量化异常处理程序功能取得了很好的成功(请参阅MSDN AddVectoredExceptionHandler)。传递给处理程序的EXCEPTION_POINTERS结构可与MiniDumpWriteDump API一起使用,以生成用户模式转储文件,您可以使用WinDbg打开该文件以检查异常。

备注:
- 您需要在打开转储以切换到异常上下文后运行.excr。
- 向异常过滤器调用所有异常,所以一定要通过查看传递给过滤器的EXCEPTION_RECORD :: ExceptionCode来过滤那些您感兴趣的异常。