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

时间:2017-05-03 12:44:43

标签: c# c++ .net crash unmanaged

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

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

抓住"正常" throw 引发的异常对我的测试应用程序没问题。

我怎样才能发现这种例外?

1 个答案:

答案 0 :(得分:0)

从C#的角度来看,你不会发现异常。本机代码中的堆栈溢出非常糟糕。调用线程可能在堆栈上有半个对象,并且你无法解开它。

实际上,您的选择是暂停违规线程,这意味着C ++代码不会返回C#。这不是直接致命的 - 当没有CPU核心可用时,操作系统会一直挂起线程。但互斥锁将保持锁定状态等。

当违规线程被暂停时,您的C#代码应该执行紧急保存所有可以获救的东西。接下来,安排重启(Windows任务计划程序可以在这里提供帮助),并强制终止整个过程。

这遗漏了一个"小" detail:捕获堆栈溢出并挂起该线程。这可能最好用 Vectored Exception Handler 完成,它由Windows直接调用。在此异常处理程序中,检查异常对象以查看它是否是堆栈溢出。如果是这样,那么您就会遇到问题,因为您现在正在运行到最后一个堆栈页面的线程上(这也可能几乎已满)。所以,你只做两件事:打电话给ResumeThread(helperThread)然后打SuspendThread(GetCurrentThread())。帮助程序线程唤醒,回调C#以启动紧急保存,然后调用TerminateProcess