找出调用 __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 获取有关异常的信息 切换到引起异常的线程~#sk查看调用栈

学习 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 的原因的主要内容,如果未能解决你的问题,请参考以下文章

调用父类时,子类是在另一个模块

远程桌面调用失败rad_001

Dialogflow - Firestore - Webhook 调用失败。错误:UNAVAILABLE,状态:URL_UNREACHABLE,原因:UNREACHABLE_5xx,HTTP 状态代码

该数组不可调用是不是有原因?

找出可变参数宏中__VA_ARGS__的类型

练手例子_main函数调用其他函数输入字符保存