Что изменилось между Windows XP и 7, что приводит к сбою моего приложения Mono C #? - PullRequest
4 голосов
/ 26 февраля 2011

Я создал и скомпилировал приложение на C #, используя платформу Mono в Linux.Программа работает на Windows XP и Linux.Однако в тот момент, когда я запускаю его в Windows 7, происходит сбой, без какой-либо полезной информации.

Что изменилось между этими двумя версиями Windows, что может сделать это?

Исходный коддоступно в http://github.com/pstuifzand/Abacus/.

Обновление :

Когда я запускаю код под WinDBG, я получаю следующую трассировку стека.

Child-SP          RetAddr           Call Site
00000000`0016de80 000007fe`f465ffb3 KERNELBASE!RaiseException+0x3d
00000000`0016df50 000007fe`f49b7477 mscorwks!StrongNameFreeBuffer+0x51a3
00000000`0016e040 000007fe`f49b9656 mscorwks!Ordinal24+0xb957
00000000`0016e070 000007fe`f4a3c525 mscorwks!Ordinal24+0xdb36
00000000`0016e0a0 000007fe`f4a3c53b mscorwks!StrongNameSignatureVerificationEx+0x2fb5
00000000`0016e110 000007fe`f4611a2a mscorwks!StrongNameSignatureVerificationEx+0x2fcb
00000000`0016e140 000007fe`f4a96b38 mscorwks!StrongNameTokenFromPublicKey+0x744fa
00000000`0016ebc0 000007fe`f4a821f2 mscorwks!PreBindAssembly+0x24978
00000000`0016ec00 000007fe`f461795a mscorwks!PreBindAssembly+0x10032
00000000`0016ecf0 000007fe`f47114f7 mscorwks!StrongNameTokenFromPublicKey+0x7a42a
00000000`0016edb0 000007ff`001f012a mscorwks!IEE+0xd8fb
00000000`0016ee80 000007fe`f4711612 0x7ff`001f012a
00000000`0016eeb0 000007fe`f463ee13 mscorwks!IEE+0xda16
00000000`0016ef00 000007fe`f4aebc51 mscorwks!CreateAssemblyNameObject+0x5cbb
00000000`0016efa0 000007fe`f4567dc7 mscorwks!PreBindAssembly+0x79a91
00000000`0016f1e0 000007fe`f4544118 mscorwks!GetCLRFunction+0xccaf
00000000`0016f440 000007fe`f4bd7e3d mscorwks+0xf4118
00000000`0016f730 000007fe`f453651b mscorwks!GetAssemblyIdentityFromFile+0x195bd
00000000`0016fd00 000007fe`f4553e60 mscorwks+0xe651b
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoreei.dll - 
00000000`0016fd50 000007fe`f65a3309 mscorwks!CorExeMain+0xac

1 Ответ

8 голосов
/ 27 февраля 2011

Мой ответ состоит из двух частей. Первая часть показывает, как найти проблему, когда ваша программа падает, до того, как она действительно запустится. Вторая часть объясняет исправление, которое решает сбой.

Часть 1. Почему произошел сбой моей программы?

Странно то, что моя программа работала на других компьютерах и других версиях Windows. Программа не работала на компьютерах с Windows 7 (и, по-видимому, 64-разрядных). Таким образом, мой первый инстинкт был посмотреть на различия между старыми версиями Windows и более новыми версиями. Однако, похоже, что многое изменилось, так что это безнадежное дело.

Моя вторая попытка найти проблему использовала WinDbg, отладчик, который позволяет увидеть, где произошла ошибка вашей программы. Проблема с этой попыткой заключалась в том, что трассировка стека не указывала на информацию, которая помогла мне понять проблему. Сначала это на самом деле указывало мне в неправильном направлении. Я заставил меня посмотреть на подписание моей сборки. Это, однако, не было частью моей проблемы.

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

В методе Main я добавил этот код:

AppDomain.CurrentDomain.UnhandledException 
    += new UnhandledExceptionEventHandler (CurrentDomain_UnhandledException);
TraceListener log = new TextWriterTraceListener ("abacus.log");
Trace.Listeners.Add (log);
Trace.Listeners.Add (new ConsoleTraceListener ());

Обработчик исключения вызывается всякий раз, когда исключение не перехватывается. Операторы Trace инициализируют различные обработчики журналов. Добавьте /d:TRACE, чтобы включить диагностику. В классе я добавил этот метод, который печатает информацию, находящуюся внутри исключения.

static void CurrentDomain_UnhandledException (object sender, UnhandledExceptionEventArgs e) {
    try {
        Exception ex = (Exception)e.ExceptionObject;

        Trace.Write ("Whoops! Please contact the developers with the following information:\n\n" + ex.Message + ex.StackTrace + ex.InnerException.Message + ex.InnerException.StackTrace);
        Trace.Flush ();
    } finally {
        Application.Quit();
    }
}

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

Часть 2. Как остановить сбой моей программы?

В моей первой попытке я изменил настройку в MonoDevelop, которая заставляет его генерировать 32-битный код. Это не решило мою проблему.

Во второй попытке я загрузил программу под названием corflags.exe, которая включена в Windows SDK. Эта программа позволяет мне изменить флаг, который заставляет Windows запускать эту программу как 32-битную программу. Это решает мою проблему.

corflags.exe /32BIT+ program
...