Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash with a x64 .NET 4.0 application in Release mode outside of the IDE only

So, I'm experiencing a very weird issue with my little test application. And by issue, I mean it crashes... hard. No exception (at least, nothing that I could catch) is thrown, just the "Blah Blah has stopped responding..." message. It crashes ONLY when I run the app in x64, release mode and outside of the IDE. If I run it in x86 mode, or if I run it in the IDE in x64 or I run it standalone as DEBUG in x64 it works fine.

I've narrowed it down to my p/invoke PeekMessage call. So, I need the brilliant minds here to look at the crap I've written and tell me if I'm doing it right. Because, seriously, I'm about to lose my f**king mind. I've tried this on 2 computers and they both exhibit the same behaviour. I'm a little concerned that this could be a .NET 4.0 bug.

Anyway, here's my p/invoke code. Please let me know if you see anything odd or just plain stupid:

Here's the call to PeekMessage:

private static bool PeekMessage()
{
        MSG message = new MSG();                // Message to retrieve.

        return Win32API.PeekMessage(ref message, IntPtr.Zero, 0, 0, PeekMessageFlags.NoRemove);
}

Here's PeekMessage (NOTE: The suppress security attribute is on the class definition, so it is being applied):

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool PeekMessage(ref MSG msg, IntPtr hwnd, uint wFilterMin, uint wFilterMax, PeekMessageFlags flags);

Here's the MSG:

[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
        /// <summary>Window handle.</summary>
        public IntPtr hwnd;
        /// <summary>Message to process.</summary>
        public uint Message;
        /// <summary>Window message parameter 1.</summary>
        public uint wParam;
        /// <summary>Window message parameter 2.</summary>
        public uint lParam;
        /// <summary>Time message was sent?</summary>
        public uint time;
        /// <summary>Mouse pointer position.</summary>
        public Point pt;
}

And finally, the PeekMessageFlags:

internal enum PeekMessageFlags
{
        /// <summary>Keep message on the message queue.</summary>
        NoRemove = 0,
        /// <summary>Remove message from the queue.</summary>
        Remove = 1,
        /// <summary>Do not yield execution to waiting threads.</summary>
        NoYield = 2
}

I checked the event log and I got this:

Faulting application name: Tester_Graphics.exe, version: 1.0.0.0, time stamp: 0x4ec0ba85
Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x00000000000001cb
Faulting process id: 0x1260
Faulting application start time: 0x01cca299e2c21a77
Faulting application path: D:\Code\Current\Gorgon\Branches\2.x\Dorian\Examples\Tester_Graphics\bin\Release\Tester_Graphics.exe
Faulting module path: unknown
Report Id: 20ac891f-0e8d-11e1-a5d7-bcaec5753ddd

So, if you see anything not quite right, please let me know. I'd hate for this to not be my fault.

Sorry if it's not detailed enough, if you need more info, just leave a note.

like image 904
Mike Avatar asked Nov 14 '11 14:11

Mike


1 Answers

The size of lParam and wParam fields of MSG are wrong. You should use IntPtr instead of uint / int.

If you take a look at Windows Data Types you can see that:

  • LPARAM is a LONG_PTR i.e. its 32 bits in size of 32 bit platforms and 64 bits in size on 64 bit platforms.
  • PARAM is a UINT_PTR which again is 32 bits in size of 32 bit platforms and 64 bits in size on 64 bit platforms.

Conversely the int and uint types are both 32 bits in size regardless of the platform, meaning that on 64 bit platforms your MSG struct is 64 bits too small which will result in some sort of memory corruption.

like image 83
Justin Avatar answered Nov 10 '22 00:11

Justin