c# - 非托管库中的堆栈溢出导致 .NET 应用程序崩溃

标签 c# c++ .net crash unmanaged

因为我经常需要使用第三方库 - 有时它们会导致我的应用程序崩溃 - 我用 C++ 制作了一个测试库。该库有意生成堆栈溢出(通过递归调用方法)。使用 .NET 4.6 制作的测试应用程序调用导出的方法...然后崩溃。

  • 尝试捕捉?不会到达并且没有效果。
  • AppDomain.UnhandledException?不会到达并且没有效果。
  • 在自己的 AppDomain 中执行该方法?没有效果。

捕获由 throw 引发的“正常”异常对于我的测试应用程序来说没有问题。

如何捕获这种异常?

最佳答案

从 C# 的角度来看,您不会捕获异常。 native 代码中的堆栈溢出非常糟糕。调用线程可能在堆栈上有一半的对象,并且您无法将其展开。

实际上,您的选择是挂起有问题的线程,这意味着 C++ 代码不会返回到 C#。这并不是直接致命的——当没有 CPU 核心可用时,线程始终被操作系统挂起。但互斥锁将保持锁定状态等。

当有问题的线程被挂起时,您的 C# 代码应该对所有可以挽救的内容执行紧急保存。接下来,安排重新启动(Windows 任务计划程序可以在此处提供帮助),并强制终止整个进程。

这遗漏了一个“小”细节:捕获堆栈溢出并挂起该线程。这可能最好使用 vector 异常处理程序来完成,它由 Windows 直接调用。在此异常处理程序中,检查异常对象以查看是否是堆栈溢出。如果是这样,那么您就会遇到问题,因为您现在运行的线程已到达最后一个堆栈页(并且也可能几乎已满)。因此,您只需执行两件事:调用 ResumeThread(helperThread),然后调用 SuspendThread(GetCurrentThread())。辅助线程唤醒,回调 C# 以启动紧急保存,然后调用 TerminateProcess

关于c# - 非托管库中的堆栈溢出导致 .NET 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43760415/

相关文章:

c# - 创建新的 Microsoft.CodeAnalysis.CustomWorkspace - 得到 ReflectionTypeLoadException

c++ - 如何使用 avcodec 从 OpenCV::Mat 类型的 jpeg 图像创建视频?

c++ - 作业 : Making an array using pointers

c# - 如何使用不同的方法获取 Windows 用户名?

.net - Powershell System.IO.StreamReader 读取方法

c# - 在 C# 中,确定数据库是否已启动并正在运行的最佳方法是什么?

c# - 在 .NET Core 测试项目中构建时禁用/阻止 XUnit 警告

c# - 使用几乎相同的类数据填充类

c++ - 如何在模板参数中分离函数类型返回类型和参数

c# - 反序列化对 Saml2SecurityToken 的 SAML2 响应时出错