Сбой приложения x64 .NET 4.0 в режиме выпуска только за пределами среды IDE. - PullRequest
10 голосов
/ 14 ноября 2011

Итак, у меня возникла очень странная проблема с моим небольшим тестовым приложением.И под вопросом, я имею в виду, что он падает ... тяжело.Не выдается никаких исключений (по крайней мере, ничего, что я мог бы поймать), только сообщение «Бла-бла перестал отвечать ...».Вылетает ТОЛЬКО , когда я запускаю приложение в x64, в режиме выпуска и за пределами IDE .Если я запускаю его в режиме x86, или если я запускаю его в IDE в x64, или я запускаю его автономно как DEBUG в x64, он работает нормально.

Я сузил его до своего вызова p / invote PeekMessage,Итак, мне нужны блестящие умы, чтобы посмотреть на дерьмо, которое я написал, и сказать мне, правильно ли я это делаю.Потому что, серьезно, я собираюсь сойти с ума.Я пробовал это на 2 компьютерах, и они оба демонстрируют одинаковое поведение.Я немного обеспокоен тем, что это может быть ошибка .NET 4.0.

В любом случае, вот мой код p / invoke.Пожалуйста, дайте мне знать, если вы видите что-то странное или просто глупое:

Вот вызов PeekMessage:

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

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

Вот PeekMessage (ПРИМЕЧАНИЕ. Атрибут безопасности suppress находится в определении класса,так что он применяется):

[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);

Вот 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;
}

И, наконец, 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
}

Я проверил журнал событий иЯ получил это:

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

Итак, если вы видите что-то не совсем правильное, пожалуйста, дайте мне знать.Я не хотел бы, чтобы это не было моей ошибкой.

Извините, если это не достаточно подробно, если вам нужна дополнительная информация, просто оставьте записку.

1 Ответ

6 голосов
/ 14 ноября 2011

Размер полей lParam и wParam MSG неправильный. Вы должны использовать IntPtr вместо uint / int.

Если вы посмотрите на Типы данных Windows , вы увидите, что:

  • LPARAM - это LONG_PTR, то есть его 32-битные по размеру 32-битные платформы и 64-битные по размеру на 64-битных платформах.
  • PARAM - это UINT_PTR, который также имеет 32-битный размер для 32-битных платформ и 64-битный для 64-битных платформ.

И наоборот, типы int и uint имеют размер 32 бита независимо от платформы , что означает, что на 64-битных платформах ваша структура MSG слишком мала на 64 бита, что приведет к какое-то повреждение памяти.

...