Я добавил код, который компилируется чисто и только что получил эту ошибку Windows:
---------------------------
(MonTel Administrator) 2.12.7: MtAdmin.exe - Application Error
---------------------------
The exception Privileged instruction.
(0xc0000096) occurred in the application at location 0x00486752.
Я собираюсь заняться охотой за ошибками и ожидаю, что это будет какая-то глупость, которую я совершил и которая просто произвела это сообщение. Код компилируется чисто, без ошибок или предупреждений. Размер EXE-файла увеличился до 1 454 132 байта и включает ссылки на ODCS.lib, но в остальном это чистый C для Win32 API с включенной DEBUG (работает на P4 в Windows 2000).





Я видел это в Visual C++ 6.0 в 2000 году.
Библиотека отладки C++ содержала вызовы физических инструкций ввода-вывода в обработчике исключений. Если я правильно помню, это был сброс состояния в порт ввода-вывода, который раньше использовался для базовых регистров DMA, которые, как я полагаю, кто-то в Microsoft использовал для карты отладчика.
Найдите состояние ошибки, которое может быть скрытым, вызывая запуск кода диагностики.
Отлаживал, отступал и читал разборку. Это было исключение при обработке std::string, возможно, индексация с конца.
Подобные вещи обычно происходят при использовании указателей функций, указывающих на недопустимые данные. Это также может произойти, если у вас есть код, который уничтожает ваш стек возврата. Иногда бывает довольно сложно отследить подобные ошибки, потому что их обычно трудно воспроизвести.
Первая вероятность, о которой я могу думать, заключается в том, что вы можете использовать локальный массив, и он находится в верхней части объявления функции. Ваша проверка границ сошла с ума и перезаписывает адрес возврата, и это указывает на некоторую инструкцию, которую разрешено выполнять только ядру.
Привилегированная инструкция - это инструкция IA-32, выполнение которой разрешено только в Ring-0 (то есть в режиме ядра). Если вы нажимаете это в пользовательском пространстве, у вас либо действительно старый EXE, либо поврежденный двоичный файл.
Exe, который я скомпилировал с помощью VC6 около 10 секунд назад .... но он содержит ссылки на ODBC.LIB и другие библиотеки, которые могут быть довольно старыми. Это приложение не является драйвером или сервисом.
Место ошибки 0x00486752 кажется мне очень маленьким, до того места, где обычно находится исполняемый код. Я согласен с Дэниелом, мне это кажется дикой указкой.
Чтобы ответить на вопрос, привилегированная инструкция - это код операции процессора (инструкция ассемблера), который может быть выполнен только в режиме «супервизора» (или в режиме Ring-0). Эти типы инструкций обычно используются для доступа к устройствам ввода-вывода и защищенным структурам данных из ядра Windows.
Обычные программы выполняются в "пользовательском режиме" (Ring-3), который запрещает прямой доступ к устройствам ввода-вывода и т. д.
Как уже упоминалось, причиной, вероятно, является поврежденный стек или неправильный вызов указателя функции.
Как я и подозревал, я поступил глупо. Думаю, я решил это в два раза быстрее из-за некоторых подсказок в комментариях в сообщениях выше. Спасибо тем, особенно тем, кто указал на что-то в начале приложения, перезаписывающее стек. Я на самом деле нашел здесь несколько ответов, более полезных, чем сообщение, которое я пометил как ответ на вопрос, поскольку они подсказали мне и поставили в очередь, где искать, хотя я думаю, что он лучше всего резюмирует ответ.
Как оказалось, я только что добавил кнопку, превышающую максимальный размер массива, содержащего некоторую информацию о кнопках панели инструментов (которая была в стеке). Я забыл это
#define MAX_NUM_TOOBAR_BUTTONS (24)
даже существовало!
В ЦП большинства процессоров, выпущенных за последние 15 лет, есть несколько очень мощных специальных инструкций. Эти привилегированные инструкции сохраняются для приложений ядра операционной системы и не могут использоваться программами, написанными пользователем.
Это ограничивает ущерб, который написанная пользователем программа может нанести системе, и сокращает количество фактических сбоев системы.
При выполнении в режиме ядра операционная система имеет неограниченный доступ как к ядру, так и к памяти пользовательской программы.
Инструкции загрузки для базового и предельного регистров являются привилегированными.
На самом деле это VC6. Но не C++, хотя множество строк с нулевым завершением. (Я мог бы использовать новые компиляторы, но до меня доходили слухи, что VC6 на самом деле быстрее для C, чем для C++). Я сомневаюсь, что это ошибка компилятора ... (я всегда обнаруживаю, что это один из таких моментов - «о чем я думал»).