【问题标题】:IIS Managed -> Unmanaged -> Managed -> StackOverflowExceptionIIS 托管 -> 非托管 -> 托管 -> StackOverflowException
【发布时间】:2020-10-29 18:30:42
【问题描述】:

我会尽可能详细地描述我的问题,但如果需要更详细的解释,请告诉我。

为了简单起见,假设我有 3 个 DLL(实际上我有更多,但我猜这不是很重要):

  1. managed-1.dll - 托管 DLL(用 C# .NET 4.0 编写) - 处理请求并在某些请求期间调用第二个 DLL 中的非托管代码

  2. unmanaged.dll - 非托管 DLL(用老式 VC++ 6.0 编写) - 执行多个操作,有时调用第三个 DLL

  3. managed-2.dll - 托管 DLL(用 CLI/C++ .NET 3.5 编写) - 我的问题的根源

我在 3 种不同的场景中运行我的代码:

  1. 我从控制台应用程序调用 managed-1.dll - 一切正常

  2. 我从ASP.NET Development Server 拨打managed-1.dll - 一切正常

  3. 我从IIS 调用managed-1.dll - 一切正常,直到涉及整个序列managed-1.dll -> unmanaged.dll -> managed-2.dll

在场景 3 中抛出 StackOverflowException。调试器显示不涉及递归。另外很明显,异常发生在以下类型的调用堆栈中:

  • managed-1.dll::CallUnmanagedCode()
  • unmanaged.dll::SomeMethod1()
  • unmanaged.dll::SomeMethod2()
  • unmanaged.dll::CallManagedCode()
  • managed-2.dll::CallUnmanagedCode() !!标有__declspec(dllexport) 并且不使用任何托管类型!!
  • managed-2.dll::FailingMethod()!!使用托管类型;一开始(连第一行代码都没有执行)发生异常!!

还有一件更有趣的事情:调试器在FailingMethod 中显示的参数值与方法调用点中的值不同。

如果有人有任何线索,请指教。

解决方案:问题与托管-非托管无关,而是与IIS stack size 有关。对我来说,editbin 工具的使用是不可接受的解决方案。所以我的解决方案 - 在调用 unmanaged.dll 之前创建新线程并将堆栈设置为 1 MB:

var result = unchecked ((int)0x800000FF);
var thread = new Thread(() => { result = pinvoke_func(); }, 1024 * 1024); // 1MB
thread.Start();
thread.Join();

【问题讨论】:

标签: .net iis pinvoke stack-overflow unmanaged


【解决方案1】:

普通 Windows 应用程序的堆栈大小显然是 1MB,但对于 IIS,它是 256KB(请参阅http://support.microsoft.com/kb/932909)。这或许可以解释为什么应用程序在控制台应用程序中运行,而不是在 IIS 中运行。

我不确切知道 ASP.NET 开发服务器的堆栈大小,但它可能是 1MB,有关更多信息,请参阅此 SO 问题:stackoverflowexception-in-iis7-but-not-in-cassini

显然可以使用 editbin 增加 IIS 的堆栈大小。
说明见这篇文章:Stack sizes in IIS - affects ASP.NET

【讨论】:

  • 感谢您的提示!我猜这可能是我问题的根源。我会尝试增加堆栈大小并让您知道结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2018-03-19
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多