【问题标题】:Obtaining stack trace after an access violation on Windows在 Windows 上发生访问冲突后获取堆栈跟踪
【发布时间】:2009-12-04 07:58:22
【问题描述】:

我正在尝试使用 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,但我不确定我应该寻找什么。

【问题讨论】:

    标签: windows stack-trace


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 是的,我知道我不能保证我可以获得完整的堆栈跟踪,但这是关于在系统崩溃时获取尽可能多的信息,因此部分或损坏的堆栈跟踪更好总比没有。
    【解决方案2】:

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

    注意事项:
    - 您需要在打开转储后运行 .excr 以切换到异常上下文。
    - 向量异常过滤器会针对所有异常调用,因此请务必通过查看传递给过滤器的 EXCEPTION_RECORD::ExceptionCode 仅过滤掉您感兴趣的那些。

    【讨论】:

      猜你喜欢
      • 2015-10-16
      • 2010-10-11
      • 2015-06-15
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多