找出调用 __fastfail 的原因
Posted
技术标签:
【中文标题】找出调用 __fastfail 的原因【英文标题】:Find out what's calling __fastfail 【发布时间】:2015-11-29 18:44:25 【问题描述】:我有一个我不熟悉的庞大代码库,程序异常终止,因为某处的线程正在调用__fastfail
。这是基于以
...请求致命的程序退出。
调用堆栈没有符号,因为它位于 C++ 2015 运行时 (ucrtbase.dll
) 中。该调用似乎是在我的主线程以外的线程上进行的。这个神秘的线程只在问题发生之前才开始,所以我无法在调试器中捕捉到它的行为 - 我不知道是什么开始了它,以及是什么导致了整个过程。
我在我的main()
中使用__try/__catch
有SEH,所以任何未处理的异常都应该被困在那里。相反,我猜测某处会冒泡到运行时并导致__fastfail
。
我尝试使用 SEH 像 main()
一样在我的所有线程中添加,尝试挂钩 abort()
、exit()
和 terminate()
,但找不到问题。我该如何调试,有什么提示吗?
【问题讨论】:
您可以尝试在 CreateThread 上设置一个断点,看看在崩溃之前发生了什么。 ucrtbase.dll 的公共符号在符号服务器上可用。您应该能够加载它们。 嗯,它实际上并没有使用 __fastfail()。你必须深入挖掘,因为它是无法回答的。堆栈跟踪非常重要。 【参考方案1】:WinDbg
我会说这对 WinDbg 来说是一项不错的任务。 WinDbg 是Debugging Tools for Windows 的一部分,它是免费的。安装两个版本,x64 和 x86,以便您可以调试任何类型的应用程序。
-
启动 WinDbg,使用正确的位数
在 WinDbg (
File/Open executable
) 下运行您的可执行文件。它将在初始断点处停止。
Set up the symbols,至少 .symfix c:\debug\symbols
和 .reload
。正如@James McNellis 所提到的,这些符号是可用的,这将在需要时下载它们。
使用g
继续运行应用程序
重现问题
当 WinDbg 停止时,
使用.dump /ma c:\debug\mydump.dmp
创建故障转储,以便您稍后对其进行分析
使用.exr -1
获取有关异常的信息
切换到引起异常的线程~#s
用k
查看调用栈
学习 WinDbg 是一项艰巨的任务,因为大多数事情都是通过神秘的命令而不是通过 UI 完成的,但它几乎可以完成所有事情。
当您有更多线索时,对于更具体的问题,请使用windbg 标签提出其他问题。
视觉工作室
Visual Studio 还可以从 Microsoft 服务器下载符号(PDB 文件;调用堆栈信息)。
-
转到主菜单中的
Tools | Options ...
从选项菜单中选择Debugging | Symbols
如果要将文件存储在特定目录中,请输入目录名称。
这是它在 Visual Studio 2015 社区版中的样子:
【讨论】:
不应该做这么多工作。当__fastfail
中断发生时,系统将停止进程中所有线程的执行,如果有附加线程则通知调试器。只要为 ucrtbase.dll 加载了符号,就应该相当简单地向上走堆栈。 Visual Studio 调试器或 windbg 在这里都可以正常工作。【参考方案2】:
Hans 和 James 是对的,获得可读的调用堆栈对于解决这种情况至关重要。
代码库安装了一个执行快速失败的纯调用处理程序。纯处理程序属于 SEH。程序中 40 多岁的线程之一有一个纯调用错误,因为其他一些线程部分清理了问题线程然后尝试访问的程序状态。一旦我有了符号,Visual Studio 在调用 purecall 处理程序的地方闯入 C++ 运行时库,然后我将其追溯到他们安装自己的程序的程序。
他们快速失败的方式被复杂化并解析为一些显然无法被信号(SIGABRT)捕获的 RtlXXX 函数,因为我之前确实尝试过。
再次感谢大家的帮助!
【讨论】:
以上是关于找出调用 __fastfail 的原因的主要内容,如果未能解决你的问题,请参考以下文章
Dialogflow - Firestore - Webhook 调用失败。错误:UNAVAILABLE,状态:URL_UNREACHABLE,原因:UNREACHABLE_5xx,HTTP 状态代码