gpt4 book ai didi

c++ - .NET 异常处理程序在 Visual C++ 6.0 异常中导致堆栈溢出

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:09:16 25 4
gpt4 key购买 nike

我有一个用 C++ 6.0 编写的旧应用程序的插件。这些文件以下列方式连接:

  1. 开始于:C++ 6.0 .exe(第三方应用程序)
  2. loads: C++ 6.0 simple loader .dll (官方插件)
  3. 加载:C++ 10.0 简单加载程序 .dll(托管 C++/CLI)
  4. 加载其中之一:包含插件的 C# .NET 4.0 程序集
  5. 加载:C++ 6.0 .dll,它为 C# 插件提供与应用程序对话的 API

问题是,一旦将 .NET 4.0 加载到 C++ 6.0 应用程序中,下一次它抛出 native 异常时,.NET 使用矢量化异常句柄来处理异常,但最终失败了。真正糟糕的部分是 vector 异常处理程序本身抛出一个异常,然后它尝试处理该异常,但失败了,并且它陷入无限循环,直到它获得堆栈溢出异常。

这是堆栈跟踪的样子:

// The next 7 lines repeat until the stack overflows
clr.dll!CreateHistoryReader()
clr.dll!CreateHistoryReader()
clr.dll!GetMetaDataInternalInterfaceFromPublic()
ntdll.dll!_RtlpCallVectoredHandlers@12()
ntdll.dll!_RtlCallVectoredExceptionHanders@8()
ntdll.dll!_RtlDispatchException@8()
ntdll.dll!_KiUserExceptionDispatcher@8()
// Below is an example exception that causes this:
KernelBase.dll!RaiseException()
rpcrt4.dll!RpcRaiseException()
rpcrt4.dll!I_RpcTransConnectionFreePacket()
rpcrt4.dll!I_RpcBindingInqCurrentModifiedId()
rpcrt4.dll!NdrConformantStringMemorySize()
rpcrt4.dll!NdrComplexStructMarshall()
rpcrt4.dll!SimpleTypeMemorySize()
rpcrt4.dll!NdrClientCall2()
ole32.dll!ServerRegisterClsid(void* hRpc, void* phProcess, _RegInput* pregin, _RegOutput** ppregout unligned long* prpcstat
ole32.dll!CRpcResolver::NotifyStarted(_RegInput* pRegIn, _RegOutput** ppRegOut)
ole32.dll!CClassCache::ResumeProcessClassObjects()

只有两种方法可以解决这个问题,而且都不是很好:

我发现在一个简单的程序中,如果我将 .NET 完全隔离在它自己的线程上,非 .NET 线程永远不会遇到这个问题。这在实践中行不通,因为插件 API 需要对 .NET 插件进行同步回调。

我想出的另一个方法是遍历内存中的每个地址,直到对“RemoveVectoredExceptionHandler(HANDLE)”的调用成功并删除 .NET 的 vector 异常处理程序。 (我可以通过临时注册自己的VEH并以其句柄作为起点来加快搜索速度)。这往往会破坏 native 代码的调试。

有没有更好的方法来处理这个问题?

最佳答案

自从我报告此问题后,CLR 的行为似乎发生了变化。由于 CLR 现在是开源的,因此可以查看幕后发生的事情。

CLR 安装它自己的 vector 异常处理程序。在 vector 异常处理期间,它会进行堆栈检查以确保有足够的空间,除非是堆栈溢出异常。堆栈空间检查出错,当它没有时它认为它空间不足,因此它抛出堆栈溢出异常以展开堆栈以进行实际工作。

我能够通过安装 2 个 vector 异常处理程序(一个在前,一个在后)来欺骗 .NET 使应用程序不崩溃。如果是导致崩溃的异常类型,我在第一个处理程序中将异常代码更改为 STACKOVERFLOW,然后在第二个处理程序中将其改回。这样 CLR 就认为这是一个堆栈溢出异常,并且不会尝试进行堆栈探测。

关于c++ - .NET 异常处理程序在 Visual C++ 6.0 异常中导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30671918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com