"Плохая двоичная подпись" в приложении ASP.NET MVC

Мы получаем ошибку выше на некоторых страницах приложения ASP.NET MVC, когда оно развернуто на 64-битном сервере Windows 2008. Он отлично работает на наших машинах для разработки, хотя это 32-битная XP. Просто интересно, сталкивался ли кто-нибудь с этим раньше, и есть какие-нибудь предложения? Подробности следующим образом:

Плохая бинарная подпись. (Исключение из HRESULT: 0x80131192)

Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.Runtime.InteropServices.COMException: Неверная двоичная подпись. (Исключение из HRESULT: 0x80131192)

Все проекты настроены на компиляцию для любого процессора и компилируются в режиме выпуска. Сайт ASP.NET предварительно скомпилирован, а предварительно скомпилированная сборка выполняется на 64-битном агенте сборки Windows 2008 TeamCity. Заранее спасибо.

РЕДАКТИРОВАТЬ

Мы все еще страдаем от этого. Я просмотрел все двоичные файлы в каталоге bin веб-сайта, используя corflags.exe. Ни один не имеет установленного флага 32BIT, и все имеют значение CorFlags 9 за исключением Antlr3.Runtime.dll, который имеет значение 1. Проблема затрагивает только определенные страницы, и, кажется, те, которые используют FluentValidation (включая FluentValidation.Mvc и FluentValidation.xValIntegration сборки). Ни один из них не показывает ничего необычного при проверке с помощью corflags.exe, и ildasm не выявляет странно выглядящих зависимостей.

При локальном построении (32-битная Windows XP) сайт разворачивается и работает нормально. При сборке на агентах сборки (64-разрядная версия Windows 2008 Server) сайт отображает эти ошибки. Сайт работает в режиме интегрированного конвейера и не настроен на 32-разрядную версию.

Трассировка стека:

[COMException (0x80131192): Bad binary signature. (Exception from HRESULT: 0x80131192)]
   ASP.views_user_newinternal_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in e:\TeamCity\buildAgent\work\605ee6b4a5d1dd36\...Admin.Mvc\Views\User\NewInternal.aspx:53
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +115
   ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in e:\TeamCity\buildAgent\work\605ee6b4a5d1dd36\...Admin.Mvc\Views\Shared\Site.Master:26
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +115
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +240
   System.Web.UI.Page.Render(HtmlTextWriter writer) +38
   System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +94
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4240

6 ответов

Решение

Я только что видел подобную проблему, когда некоторые лямбда-выражения используются в представлениях, что приводит к повреждению DLL-библиотеки.Net при компиляции в 64-битной системе. Это приводит к тому же исключению, которое вы видите, и, безусловно, звучит как вероятный кандидат.

Извинения, если это кажется немного расплывчатым, так как мы не решили это полностью и все еще изучаем, хотя я обязательно обновлю здесь, когда у нас будет решение.

След, который заставляет нас поверить, что это действительно поврежденная dll, заключается в том, что если вы просматриваете свой dll скомпилированного представления в ildasm.exe и изучаете фактический вызов метода с использованием lamda, вы получаете ошибку "[SIGNATURE ENDED PREMATURELY]", показанную в ILDASM. Рефлектор RedGate, однако, падает при попытке расширить метод.

В нашем случае ildasm выглядит так:

IL_029f:  call class [System.Core]System.Linq.Expressions.Expression`1<!!0> [System.Core]System.Linq.Expressions.Expression::Lambda<class [System.Core]System.Func`2<class [MyCode.Authentication.Admin.Mvc]MyCode.Authentication.Admin.Mvc.Dto.InternalUserDto,object>>(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
IL_02a4:  call class [System.Web.Mvc]System.Web.Mvc.HtmlHelper [MyCode.Extensions]MyCode.Extensions.System.Web.Mvc.HtmlHelperInputExtensions::CheckBox<[2]>(class [System.Core]System.Linq.Expressions.Expression`1<class [System.Core]System.Func`2<class [MyCode.Extensions]'type parameter'.T,object>> [SIGNATURE ENDED PREMATURELY])

Мы заметили, что это только 64-битная проблема. Мы собираемся выяснить, по-прежнему ли эта проблема возникает в.Net 4.0. Я обновлю здесь, когда мы узнаем.

Мы также находимся в процессе выяснения, было ли это поднято как ошибка с Microsoft. Снова, я обновлю здесь, когда мы узнаем.

[РЕДАКТИРОВАТЬ: теперь доходит до коренной причины проблемы]

Я думал, что вернусь и обновлю этот ответ.

Для нас оказалось, что это не проблема компилятора, а проблема с aspnet_merge. Короче говоря, на наших 64-битных сборочных блоках мы использовали более старую, устаревшую копию aspnet_merge (случайно), которая, казалось, работала, но привела к этим поврежденным dll (именно так, как вы описываете). Путь был изменен, поэтому наш проект веб-развертывания использовал эту неправильную версию.

Обновление пути к aspnet_merge версии 3.5 или выше исправило проблему.

Мы изначально думали, что это 64-битная проблема, потому что наши блоки сборки были единственной 64-битной средой, на которой мы скомпилировали (все наши рабочие станции 32-битные), и единственной, которая имела эту проблему. Однако "битность" была красной селедкой!

Надеюсь, это поможет вам решить вашу проблему.

Возможно ли исключить серьезную проблему с сервером или его программным обеспечением?

Судя по трассировке и вашему комментарию о строке 53, я бы серьезно отнесся к чему-то поврежденному, не связанному с вашим кодом, т.е. я ожидал, что любой связанный с ним код.net будет влиять на стек ошибки.

BadgerB в этой теме может быть о чем-то:

Я ошибаюсь или эта ошибка должна быть вызвана значительным изменением dll (изменяется сигнатура вызова метода) без перекомпиляции кода, который использует dll для учета новой сигнатуры.

Похоже, разница между рабочим и нерабочим сценариями заключается в том, что машина / среда используются для создания двоичных файлов. Может ли быть так, что при сборке с TeamCity на 64-битной машине интерфейс или сигнатура какого-либо метода изменяется, что вызывает эту ошибку?

Можете ли вы опубликовать полный стек вызовов, когда происходит это исключение? Есть ли какие-либо COM-объекты или вызовы P/Invoke для собственного кода? Вы используете какой-нибудь нативный код?

Звучит так, будто вы вызываете 32-битный компонент COM. Вам, вероятно, нужно либо запустить приложение в 32-битном режиме, либо изменить свою зависимость.

См. Сообщение Скотта Хансельмана для получения дополнительной информации.

http://www.hanselman.com/blog/32bitnessAnd64bitnessAndMigratingDasBlogOnIIS7AndASPNETUnderVista64.aspx

Просто поместите это там, на случай, если другие найдут этот вопрос.

У меня была похожая проблема, хотя сообщение об ошибке немного отличалось:System.BadImageFormatException: Bad binary signature. (Exception from HRESULT: 0x80131192)

Я отследил проблему до лямбды, передаваемой между проектом веб-сайта.NET 4.0 и библиотекой классов 3.5 после предварительной компиляции с использованием aspnet_merge,

Проблема появилась только после установки VS2012 (и его обновления на месте.NET 4.0 до 4.5).

Связанный вопрос "Плохая двоичная подпись" в приложении ASP.NET MVC, казалось, был более специфичным для обнаруженной мной проблемы, поэтому я дал более подробный ответ там.

Надеюсь, это поможет.

Поскольку это был мой самый важный источник за последние три дня расследования, я опубликую свое решение здесь.

Как и другие, сообщавшие об этой проблеме, у нас была успешная 32-битная среда развертывания, работающая под управлением TeamCity, но мы переходим на 64-битную, единственное место, где это происходит. Он также появляется только на определенных страницах, а не "периодически" или "случайно", как некоторые сообщают.

После методического исключения целого ряда вещей (преимущественно версии aspnet_merge.exe и среды) и поиска страницы MVC, где я мог воспроизвести проблему, я решил, что это проблема кода. Другие места также указывали на то, что лямбда-выражения являются причиной, что в некоторой степени верно и для нас. Следующий код относится только к коду в представлениях.

Чтобы добраться до сути, неверный код или нет, это будет работать на aspnet_merge.exe версии 4.x, работающей на 32-битной:

Model.MyEvents.Distinct(x => x.CategoryName).Many()

Где, как на aspnet_merge.exe версии 4.x на 64-битной, он должен быть записан как:

Model.MyEvents.Distinct((x, y) => x.CategoryName == y.CategoryName).Many()

Я знаю, что подсказка есть в названии IEquality * Comparer *, которое логически должно принимать два аргумента, но первая версия будет компилироваться и работать в 32-битной среде.

Я просто надеюсь, что этот пост поможет другим в такой же ситуации. Тогда я уверен, что кто-то сможет расшифровать это и разобрать до 32-битной 64-битной проблемы IntPtr некоторого причудливого типа.

Другие вопросы по тегам