msvcr71.dll срива IIS 7 набор от приложения на Windows Server 2008 с ASP.NET 4

Работя върху проект, който изисква C библиотека, която съм обвил с управляван код. Библиотеката C е компилирана за 32-битова и разбрах, че изисква msvcr71.dll. Проблемът е, че тази DLL не се доставя с Windows Server 2008 в директорията SysWOW64 по някаква причина.

Копирах DLL от SQL Management Studio в системата и мога да проверя дали работи в самостоятелен EXE на сървъра. Нищо не пречи да работи.

ОБАЧЕ... когато го свържа с моето ASP.NET приложение и се уверя, че DLL на моята библиотека и msvcr71.dll са в моята /bin директория, наборът от приложения за моя сайт изчезва от мен. werfault.exe се задейства, изяжда много CPU и RAM, след което си отива и ми оставя този почти безполезен журнал в Event Viewer.

След това наборът от приложения се рестартира и изчаква да се провали отново. Работи с .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


person jocull    schedule 08.08.2012    source източник


Отговори (1)


Мразя да отговарям на собствения си въпрос, но се нуждае от решение, записано за всички останали. Основният проблем, който имах тук, всъщност не беше msvcr71.dll (помислих си, че в крайна сметка успях да прекомпилирам оригиналния C източник за въпросната библиотека спрямо версия 10 на C runtime msvcr100.dll, тъй като той е включен в Windows Server 2008 по подразбиране.

Все още изпълнявам библиотеката срещу x86. Въпреки това истинският проблем тук е, че има някакъв вид грешка в управлението на паметта (или функция, вие решавате), която причинява срив на IIS 7, когато се прави Interop на P/Invokes с низове в .NET. Мисля, че беше предназначено като защитна функция... кой знае.

Вижте статията, посочена в актуализацията на въпроса по-горе, за частични подробности по този въпрос:

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

Конкретната библиотека, с която работя, е за Shapefiles от ГИС инструменти, ако сте толкова любопитни.

http://shapelib.maptools.org/

Това имаше някакъв смисъл за мен, но моята библиотека е написана на C, а не на C++. Независимо от това нито един от двата езика не ми е силна страна и не можах да намеря CoTaskMemFree метод, който съществуваше в C компилатора. Вероятно аз съм виновен, но наистина нямах време да науча и пренапиша някой древен 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 и да го анализирам сам.

person jocull    schedule 09.08.2012
comment
Друго нещо, което трябва да забележите е, че ASP.NET зарежда само msvcr71.dll от SysWOW64. Не поставяйте такива неуправляеми зависимости в папката bin, тъй като няма да работи. - person Lex Li; 09.08.2012
comment
В крайна сметка изобщо не използвах тази DLL, но благодаря за съвета. Вместо това прекомпилирах спрямо най-новата версия 10 C runtime. - person jocull; 10.08.2012