简体   繁体   English

仅在IDE之外的发布模式下使用x64 .NET 4.0应用程序崩溃

[英]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. 不会引发任何异常(至少,我无法捕捉到任何异常),只是“ Blah Blah已停止响应...”消息。 It crashes ONLY when I run the app in x64, release mode and outside of the IDE . 当我在x64,发布模式和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. 如果我在x86模式下运行它,或者在x64的IDE中运行它,或者在x64的调试模式下独立运行它,则效果很好。

I've narrowed it down to my p/invoke PeekMessage call. 我已将其范围缩小到我的p /调用PeekMessage调用。 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. 我有点担心这可能是.NET 4.0错误。

Anyway, here's my p/invoke code. 无论如何,这是我的P /调用代码。 Please let me know if you see anything odd or just plain stupid: 请让我知道,如果您看到任何奇怪或只是愚蠢的事情:

Here's the call to PeekMessage: 这是对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): 这是PeekMessage(注意:抑制安全性属性在类定义上,因此已被应用):

[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: 最后,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. 抱歉,如果不够详细,如果您需要更多信息,请留下备注。

The size of lParam and wParam fields of MSG are wrong. MSGlParamwParam字段的大小错误。 You should use IntPtr instead of uint / int . 您应该使用IntPtr而不是uint / int

If you take a look at Windows Data Types you can see that: 如果查看Windows数据类型,您会看到:

  • LPARAM is a LONG_PTR ie its 32 bits in size of 32 bit platforms and 64 bits in size on 64 bit platforms. LPARAM是一个LONG_PTR即32位平台的大小为32位,而64位平台的大小为64位。
  • 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. PARAM是一个UINT_PTR ,它也是32位平台的大小为32位,在64位平台上的大小为64位。

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. 相反, 无论平台如何, intuint类型的大小均为32位,这意味着在64位平台上,您的MSG结构太小了64位,这将导致某种形式的内存损坏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM