【问题标题】:msvcr71.dll crashing IIS 7 app pool on Windows Server 2008 w/ ASP.NET 4msvcr71.dll 在带有 ASP.NET 4 的 Windows Server 2008 上使 IIS 7 应用程序池崩溃
【发布时间】:2012-08-08 08:53:06
【问题描述】:

我正在处理一个需要使用托管代码封装的 C 库的项目。 C 库是为 32 位编译的,我发现它需要 msvcr71.dll。问题是无论出于何种原因,此 DLL 在 SysWOW64 目录中都没有随 Windows Server 2008 一起提供。

我已经从系统上的 SQL Management Studio 复制了 DLL,并且我可以验证它是否可以在服务器上的独立 EXE 中运行。没有什么可以阻止它工作。

但是...当我将它链接到我的 ASP.NET 应用程序并确保我的库的 DLL 和 msvcr71.dll 都在我的 /bin 目录中时,我的网站的应用程序池从我下面掉出来了。 werfault.exe 启动,吃掉一堆 CPU 和 RAM,然后离开并在事件查看器中留下这个几乎无用的日志。

然后应用程序池重新启动并等待再次失败。它在集成模式下与 .NET 4 一起运行。该网站基于 MVC 3。

Faulting application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7a5f8
Faulting module name: ntdll.dll, version: 6.1.7601.17725, time stamp: 0x4ec49b8f
Exception code: 0xc0000374
Fault offset: 0x000ce6c3
Faulting process id: 0x998
Faulting application start time: 0x01cd753eb1fcd760
Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\Windows\SysWOW64\ntdll.dll
Report Id: 7b54f020-e132-11e1-a34d-404094d3cf82

这里到底发生了什么?我很想将 DLL 直接链接到我的 ASP.NET 站点,但我正处于编写代理应用程序的边缘……如果可能的话,我想避免这种黑客攻击。谢谢。

旁注所有这些都可以在我的本地机器上完美运行。只有在服务器上,我才很难将它链接到 IIS。

更新

在 IIS 中运行时,这似乎是一个互操作问题,尤其是使用字符串方法时...我现在正在研究它...

http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx

【问题讨论】:

    标签: asp.net windows-server-2008 32bit-64bit


    【解决方案1】:

    讨厌回答我自己的问题,但它需要为其他人记录一个解决方案。我在这里遇到的核心问题实际上并不是msvcr71.dll(最终我认为我确实最终针对C运行时msvcr100.dll的版本10重新编译了相关库的原始C源代码,因为它包含在Windows Server 2008中默认。

    我仍在针对 x86 运行该库。然而,真正的问题是,在使用 .NET 中的字符串对 P/Invokes 执行互操作时,存在某种内存管理错误(或功能,由您决定)导致 IIS 7 崩溃。我认为这是一种安全功能……谁知道呢。

    查看上面问题更新中列出的文章,了解有关此问题的部分详细信息:

    http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx

    如果你好奇的话,我正在使用的特定库是 GIS 工具中的 Shapefiles。

    http://shapelib.maptools.org/

    这对我来说有些道理,但我的库是用 C 而不是 C++ 编写的。无论如何,这两种语言都不是我的强项,我找不到 C 编译器中存在的 CoTaskMemFree 方法。这可能是我自己的错,但我真的没有时间学习和重写一些古老的C代码。

    我发现我不能使用 .NET 方法将字符串编组回来,而是从 IntPtr 手动执行以防止 IIS 崩溃。

    这是我原来的导入:

        [DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
    public static extern string DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
    

    ...这就是我必须将其更改为:

        [DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
    public static extern IntPtr DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
    

    该更改本身阻止了应用程序崩溃。然后我不得不创建这种技巧来拉出弦乐。我知道这远非乐观,但这是我目前能做的最好的。

    这就是我最终做了什么......

    public static string DBFReadStringAttribute(IntPtr hDBF, int iShape, int iField)
    {
        IntPtr dataPtr = _DBFReadStringAttribute(hDBF, iShape, iField);
        string output = Marshal.PtrToStringAnsi(dataPtr, 255); //255 is the supposed max length for DBF databases
        int idx = output.IndexOf('\0');
        string strData;
        if (idx > 0)
            strData = output.Substring(0, idx).Trim();
        else
            strData = "";
    
        return strData;
    }
    
    [DllImport("shapelib.dll", CharSet = CharSet.Ansi, EntryPoint = "DBFReadStringAttribute")]
    private static extern IntPtr _DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);
    

    补充说明

    无论出于何种原因Marshal.PtrToStringAnsi(dataPtr) 没有正确检索字符串(它会损坏)。我必须设置一个 maxlength 并自己解析它。

    【讨论】:

    • 您应该注意的另一件事是 ASP.NET 仅从 SysWOW64 加载 msvcr71.dll。不要将此类非托管依赖项放在 bin 文件夹中,因为它不起作用。
    • 最后我根本没有使用那个DLL,但是谢谢你的提示。我改为针对最新的 10 版 C 运行时重新编译。
    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 2012-12-18
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多