28

我添加了一些可以干净编译的代码,并且刚刚收到此 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,但它是 Win32 API 的纯 C 语言,带有 DEBUG(在 Windows 2000 上的 P4 上运行)。

4

9 回答 9

38

为了回答这个问题,特权指令是处理器操作码(汇编指令),只能在“主管”(或 Ring-0)模式下执行。这些类型的指令往往用于从 Windows 内核访问 I/O 设备和受保护的数据结构。

常规程序以“用户模式”(Ring-3)执行,不允许直接访问 I/O 设备等...

正如其他人所提到的,原因可能是堆栈损坏或函数指针调用混乱。

于 2008-09-18T03:23:03.027 回答
7

当使用指向无效数据的函数指针时,通常会发生这种事情。如果您的代码破坏了返回堆栈,也可能发生这种情况。有时很难追踪这类错误,因为它们通常难以重现。

于 2008-09-18T03:03:46.973 回答
7

特权指令是仅允许在 Ring-0(即内核模式)中执行的 IA-32 指令。如果你在用户空间中遇到这个问题,你要么有一个非常旧的 EXE,要么是一个损坏的二进制文件。

于 2008-09-18T03:04:22.340 回答
5

正如我所怀疑的那样,我这样做很愚蠢。我想我解决这个问题的速度快了两倍,因为上面消息中的评论中有一些线索。感谢那些人,尤其是那些指出应用程序早期覆盖堆栈的人。实际上,我在这里发现了几个答案比我标记为回答问题的帖子更有用,因为他们提示并排队我看哪里,尽管我认为它最好地总结了答案。

事实证明,我刚刚添加了一个按钮,该按钮超过了包含一些工具栏按钮信息(位于堆栈上)的数组的最大大小。我忘记了

#define MAX_NUM_TOOBAR_BUTTONS (24)

甚至存在!

于 2008-09-18T03:54:30.173 回答
4

我能想到的第一个可能性是,您可能正在使用本地数组,并且它位于函数声明的顶部附近。您的边界检查变得疯狂并覆盖了返回地址,它指向了一些只允许内核执行的指令。

于 2008-09-18T03:04:03.557 回答
2

我在 2000 年使用 Visual c++ 6.0 看到了这一点。

调试 C++ 库在异常处理程序中调用了物理 I/O 指令。如果我没记错的话,它会将状态转储到曾经用于 DMA 基址寄存器的 I/O 端口,我假设微软的某个人正在使用它作为调试器卡。

查找可能导致诊断代码运行的潜在错误情况。

我正在调试,回溯并阅读反汇编。在处理时这是一个异常 std::string,可能是索引结束。

于 2008-09-18T03:01:57.603 回答
2

错误位置 0x00486752 对我来说似乎真的很小,在可执行代码通常存在的位置之前。我同意丹尼尔,这对我来说似乎是一个疯狂的指针。

于 2008-09-18T03:10:28.860 回答
2

The CPU of most processors manufactured in the last 15 years have some special instructions which are very powerful. These privileged instructions are kept for operating system kernel applications and are not able to be used by user written programs.

This restricts the damage that a user-written program can inflict upon the system and cuts down the number of times that the system actually crashes.

于 2009-11-02T12:32:25.357 回答
2

When executing in kernel mode, the operating system has unrestricted access to both the kernel and the user program's memory.

The load instructions for the base and limit registers are privileged instructions.

于 2010-12-12T19:18:54.273 回答