在Windows上发生访问冲突后获取堆栈跟踪

时间:2009-12-04 07:58:22

标签: windows stack-trace

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

[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

我怀疑涉及奇怪的Windows异常处理和setjmp / longjmp,但我不确定我应该寻找什么。

2 个答案:

答案 0 :(得分:2)

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

在这种情况下,您似乎正在尝试捕获异常过滤器中的堆栈跟踪,这将永远不会起作用 - 异常过滤器在部分展开的堆栈上运行。您可以使用GetExceptionInformation API找到失败的异常记录和上下文记录(此API仅适用于过滤器表达式,因此您需要执行类似

的操作
  __try
  {
     <stuff>
  }
  __except(MyExceptionFilter(GetExceptionInformation())
  {
     <stuff>
  }

您应该能够使用上下文记录和异常信息检索准确的堆栈跟踪。

答案 1 :(得分:0)

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

注意:
- 打开转储后需要运行.excr才能切换到异常上下文 - 为所有异常调用矢量异常过滤器,因此请务必通过查看传递给过滤器的EXCEPTION_RECORD :: ExceptionCode来过滤掉您感兴趣的异常过滤器。