Что такое привилегированная инструкция? - PullRequest
25 голосов
/ 18 сентября 2008

Я добавил некоторый код, который аккуратно компилируется и только что получил эту ошибку 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).

Ответы [ 9 ]

33 голосов
/ 18 сентября 2008

Чтобы ответить на вопрос, привилегированная инструкция - это код операции процессора (инструкция на ассемблере), который может быть выполнен только в режиме «супервизор» (или Ring-0). Эти типы инструкций обычно используются для доступа к устройствам ввода-вывода и защищенным структурам данных из ядра Windows.

Обычные программы выполняются в «пользовательском режиме» (Ring-3), что запрещает прямой доступ к устройствам ввода-вывода и т. Д. *

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

7 голосов
/ 18 сентября 2008

Привилегированная инструкция - это инструкция IA-32, которую разрешено выполнять только в Ring-0 (то есть в режиме ядра). Если вы нажмете это в пользовательском пространстве, у вас либо действительно старый EXE-файл, либо поврежденный двоичный файл.

7 голосов
/ 18 сентября 2008

Такого рода вещи обычно происходят при использовании указателей на функции, которые указывают на недопустимые данные. Это также может произойти, если у вас есть код, который очищает ваш стек возврата. Иногда бывает довольно сложно отследить подобные ошибки, потому что их обычно трудно воспроизвести.

4 голосов
/ 18 сентября 2008

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

Как оказалось, я только что добавил кнопку с максимальным размером массива, содержащую некоторую информацию о кнопках панели инструментов (которая была в стеке). Я забыл, что

#define MAX_NUM_TOOBAR_BUTTONS  (24)

даже существовал!

4 голосов
/ 18 сентября 2008

Первая вероятность, о которой я могу подумать, это то, что вы можете использовать локальный массив, и он находится в верхней части объявления функции. Ваша проверка границ сошла с ума и перезаписывает адрес возврата, и он указывает на некоторую инструкцию, которую может выполнять только ядро.

2 голосов
/ 12 декабря 2010

При выполнении в режиме ядра операционная система имеет неограниченный доступ как к ядру, так и к памяти пользовательской программы.

Инструкции загрузки для базового и предельного регистров являются привилегированными инструкциями.

2 голосов
/ 02 ноября 2009

ЦП большинства процессоров, изготовленных за последние 15 лет, имеют несколько очень мощных специальных инструкций. Эти привилегированные инструкции сохраняются для приложений ядра операционной системы и не могут использоваться пользовательскими программами.

Это ограничивает ущерб, который может нанести написанная пользователем программа системе, и сокращает количество аварийных сбоев системы.

2 голосов
/ 18 сентября 2008

Местоположение ошибки 0x00486752 кажется мне очень маленьким, до того места, где обычно живет исполняемый код. Я согласен с Даниэлем, это выглядит как дикий указатель на меня.

2 голосов
/ 18 сентября 2008

Я видел это с Visual C ++ 6.0 в 2000 году.

В библиотеке отладочной C ++ были вызовы физических инструкций ввода-вывода в обработчике исключений. Если я правильно помню, это был дамп статуса на порт ввода-вывода, который использовался для базовых регистров DMA, который, как я полагаю, кто-то в Microsoft использовал для карты отладчика.

Проверьте наличие ошибки, которая может быть латентной, что приводит к выполнению диагностического кода.

Я отлаживал, возвращал и читал разборку. Это было исключение при обработке std::string, возможно, индексирование до конца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...