Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What has changed between Windows XP and 7 that crashes my Mono C# application?

I created and compiled a C# application using the Mono framework on Linux. The program works on Windows XP and Linux. However the moment I start it on Windows 7, it crashes, without any useful information.

What has changed between these two version of Windows, that could makes this happen?

The source code is available at http://github.com/pstuifzand/Abacus/.

Update:

When I run the code under WinDBG I get the following stack trace.

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
like image 441
Peter Stuifzand Avatar asked Feb 25 '23 23:02

Peter Stuifzand


1 Answers

My answer contains two parts. The first part shows how to find the problem when your program crashes, before it actually starts. The second part explains the fix that solves the crash.

Part 1 - Why did my program crash?

The strange thing is, that my program worked on other computers and other versions of Windows. The program didn't work on Windows 7 (and apparently 64-bit) computers. So my first instinct was to look at the differences between older versions of Windows and newer versions. It seems however there many things changed so this is a lost cause.

My second attempt to find the problem used WinDbg, a debugger that allows you to see where your program crashed. The problem with this attempt was that the stacktrace didn't point to information that helped me understand to problem. It actually pointed me in the wrong direction at first. I made me look at signing my assembly. This however wasn't part of my problem.

The third attempt made me take a look at which exception was thrown from inside the program. I did this by adding a bit of logging code and the unexpected exception handler.

In the Main method I added this code:

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

The exception handler is called whenever an exception isn't caught. The Trace statements initialize various logging handlers. Add /d:TRACE to enable the diagnostics. In the class I added this method, which print the information that's inside the exception.

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();
    }
}

Running this enhanced program resulted in a log message with exception information. With this log message I found a message, that explained why my program is crashing. I try to load 64-bit version of assemblies, that aren't available as 64-bit, only 32-bit. And that's the problem.

Part 2 - How to stop my program from crashing?

In my first attempt I changed a setting in MonoDevelop, that makes it generate 32-bit code. This didn't solve my problem.

In my second attempt I downloaded a program called corflags.exe, which is included in the Windows SDK. This program allows me change a flag, which makes Windows run this program as a 32-bit program. This solves my problem.

corflags.exe /32BIT+ program
like image 175
Peter Stuifzand Avatar answered Apr 06 '23 12:04

Peter Stuifzand