Моя полностью управляемая сборка аварийно завершает работу с AccessViolationException в .Net 4.5?

Я отлаживал очень сложную проблему.

По сути, у меня есть запутанная сборка, которая вылетает по-разному. Необфусцированная сборка не имеет проблем, хотя нет никакой гарантии, что обфускатор здесь не виноват. (это то, что я мог бы стремиться исправить)

Во всяком случае, запутанная сборка также отлично работает на .Net 4.0. Он работает нормально, если я отключу оптимизацию JIT в .Net 4.5.

Что я пробовал:

Я попытался отладить его против IL. Нарушение прав доступа происходит из-за операции IL, которая просто загружает что-то в стек. Опять же, полностью управляемый код.

На всякий случай это связано с String.Empty я прошел IL и заменил все вызовы string::empty на ldstr "".. Теперь вместо AccessViolation я получаю FatalEngineException

Однако запуск его через деобфускатор со всеми отключенными параметрами заставляет его работать. По сути, все, что делает деобфускатор, когда ничего не включено, — это просто перестраивает IL и вставляет несколько NOP.

Кроме того, исполняемый файл проходит PEVerify, так что это не проблема.

Плохой исполняемый файл: Test.exe

Хороший исполняемый файл: Test-cleaned.exe

Оскорбительная трассировка стека:

Test.exe!PreEmptive.SoS.Client.Cache.CacheService.ServiceCache() Line 22032 + 0x137 bytes   Unknown
Test.exe!Test.TestConsole.Main(string[] args) Line 14 + 0x6 bytes   Unknown

Вы можете использовать ildasm для сравнения двух исполняемых файлов. Однако, поскольку он переупорядочен, на мой вкус он показался мне слишком сложным. Я сделал небольшой инструмент, чтобы просто сбросить IL метода и иметь методы в отсортированном порядке для простота сравнения.

Плохой дамп IL: testcount.il

Хороший дамп IL: testcountcleaned.il

В любом случае, если у кого-нибудь есть какие-либо идеи о том, как проанализировать это и выяснить, какие именно части IL вызывают это, я был бы признателен.


person Earlz    schedule 07.09.2012    source источник


Ответы (1)


Решение заключалось в том, что у нас действительно была небольшая часть P/Invoking. .Net 4.5 более агрессивно использует память. По какой-то причине инструмент, который мы использовали, удалил атрибут Marshalling в одной из наших структур. После исправления этой ошибки все волшебным образом работает. Так что это вовсе не ошибка .Net 4.5. Он просто использует память более агрессивно.

person Earlz    schedule 12.09.2012