windows 访问冲突“0xc0000005”的范围究竟是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5303524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:10:49  来源:igfitidea点击:

What exactly is the scope of Access Violation '0xc0000005'?

windowswinapiexception

提问by sebf

I was wondering about exception 0xc0000005 and what it acctually encompasses.

我想知道异常 0xc0000005 及其实际包含的内容。

I.e. I take it this occurs if an application tries to access freed memory/memory belonging to another process.
But what about, for example, an address mapped for hardware? Or an address outside the valid range? Do attempted accesses to these fault with the same code or do they have their own? Does this include failed reads to valid addresses owned by the process?

即我认为如果应用程序尝试访问属于另一个进程的已释放内存/内存,则会发生这种情况。
但是,例如,为硬件映射的地址呢?还是有效范围之外的地址?尝试使用相同的代码访问这些故障还是它们有自己的故障?这是否包括对进程拥有的有效地址的读取失败?

Essentially I want to know when an application fails with this exception, what may have gone wrong; is this a narrow fault that could only have come from the apps. code or am I looking at anything up and including hardware problems?

本质上,我想知道应用程序何时因此异常而失败,可能出了什么问题;这是一个狭窄的错误,只能来自应用程序。代码还是我正在查看任何内容并包括硬件问题?

(I know there must be an MSDN page on this but searching Google or MSDN brings up the expected 100 pages of troubleshooting random applications ;))

(我知道必须有一个 MSDN 页面,但是搜索 Google 或 MSDN 会带来预期的 100 页的随机应用程序故障排除页面;))

Thanks!

谢谢!

回答by Hans Passant

You need to read the processor manual to drill this down. It is triggered by a "trap", best described as an exception in the processor. A trap interrupts code execution and lets an operating system "catch" handler deal with the fault. A very common benign one is a page fault, raised when the processor tries to read data from RAM that isn't mapped yet. That's how virtual memory is implemented.

您需要阅读处理器手册才能深入了解。它由“陷阱”触发,最好将其描述为处理器中的异常。陷阱会中断代码执行并让操作系统“捕获”处理程序来处理错误。一个非常常见的良性错误是页面错误,当处理器尝试从尚未映射的 RAM 读取数据时引发。这就是虚拟内存的实现方式。

An AccessViolation belongs to a group of traps that are hard faults that the operating system doesn't know how to handle. It is called "General Protection Fault" in the processor manual. It's a bit of a grab-bag, there are lots of ways to trigger a GPF. By far the most common one is trying to read memory that isn't mapped, usually caused by heap memory corruption. Followed by trying to execute a machine code instruction that isn't valid or can only be executed by privileged code, usually caused by stack memory corruption.

AccessViolation 属于一组陷阱,这些陷阱是操作系统不知道如何处理的硬故障。它在处理器手册中称为“一般保护故障”。这有点像抓包,有很多方法可以触发 GPF。到目前为止,最常见的是尝试读取未映射的内存,这通常是由堆内存损坏引起的。随后尝试执行无效或只能由特权代码执行的机器代码指令,通常是由堆栈内存损坏引起的。

These traps are as nasty as they come, the processor simply cannot continue executing the program. The operating system certainly doesn't know how to handle it, it raises an AccessViolation exception to give the program a shot at jerking the processor back to known-good code. Possible by using the __try/__exceptkeywords in your code. Not a great idea btw, other than for custom error reporting, you have no real idea how the state of your program got mutated before it died and thus no way to restore it back.

这些陷阱来之不易,处理器根本无法继续执行程序。操作系统当然不知道如何处理它,它会引发 AccessViolation 异常,让程序有机会将处理器拉回已知良好的代码。可以通过__try/__except在代码中使用关键字来实现。顺便说一句,这不是一个好主意,除了用于自定义错误报告之外,您不知道程序的状态在它死之前是如何发生变异的,因此无法将其恢复。

Without such an SEH handler, this ends up in a backstop that Windows provides. You can provide your own with SetUnhandledExceptionFilter(), useful to customize the crash report. The system-provided one puts an end to it by triggering WER, the Windows Error Reporting component. Which ultimately terminates the process.

如果没有这样的 SEH 处理程序,最终会出现 Windows 提供的支持。您可以提供您自己的SetUnhandledExceptionFilter(),这对自定义崩溃报告很有用。系统提供的一个通过触发 WER(Windows 错误报告组件)来结束它。最终终止该过程。

回答by Ben Voigt

First, you need to understand that addresses in a user-mode process are virtual addresses. They are not the actual addresses used to access hardware. Rather, there is a virtual-to-physical translation circuit in the CPU (part of the memory management unit) which finds a matching entry in the "Translation Lookaside Buffer". During each context switch, the OS fills the TLB with the memory mappings belonging to your process.

首先,您需要了解用户模式进程中的地址是虚拟地址。它们不是用于访问硬件的实际地址。相反,CPU(内存管理单元的一部分)中有一个虚拟到物理转换电路,它在“转换后备缓冲区”中找到匹配的条目。在每次上下文切换期间,操作系统用属于您的进程的内存映射填充 TLB。

So there is no way to try to access memory belonging to other processes, nor can you try to access hardware. It's not that this access is detected and fails, it's that no mapping exists for memory that does not belong to your program.

所以没有办法尝试访问属于其他进程的内存,也不能尝试访问硬件。不是检测到此访问并失败,而是不属于您的程序的内存不存在映射。

If your program accesses an address that does not map to anywhere, a trap will occur as Hans said. It's the same trap for "page faults" and "access violations". First the OS will check if the address is valid but not in the TLB (for example, your PC ran out of memory and some was swapped out to disk). In that case the OS will move the data back into physical RAM, set the proper mapping in the TLB, and continue running your program. If the OS determines that the address is completely invalid (there's no swap location associated with it), it will generate an "access violation" (Windows naming) or "segmentation fault" (POSIX naming).

如果你的程序访问了一个没有映射到任何地方的地址,就像汉斯所说的那样,就会发生陷阱。这与“页面错误”和“访问冲突”的陷阱相同。首先,操作系统将检查地址是否有效但不在 TLB 中(例如,您的 PC 内存不足,有些已换出到磁盘)。在这种情况下,操作系统会将数据移回物理 RAM,在 TLB 中设置正确的映射,然后继续运行您的程序。如果操作系统确定地址完全无效(没有与之关联的交换位置),它将生成“访问冲突”(Windows 命名)或“分段错误”(POSIX 命名)。

Usually the cause is a logic bug, but if you had e.g. a RAM failure that changed a bit in one of your pointers, the hardware failure could trigger an access violation also.

通常原因是逻辑错误,但如果您有例如 RAM 故障,其中一个指针发生了一些变化,则硬件故障也可能触发访问冲突。

回答by MSN

I got thisas my first result for "access violation" (no quotes) on google. I'm not sure of the specifics, but an AV just means that: the processor tried to read from or write to a particular address that its current state did not allow. It could be a hardware issue, a bus error, unmapped virtual memory, bad CPU; pretty much anything that indicates violating access protections.

我得到了这个作为我在谷歌上“访问冲突”(没有引号)的第一个结果。我不确定具体细节,但 AV 只是意味着:处理器试图读取或写入其当前状态不允许的特定地址。可能是硬件问题、总线错误、未映射的虚拟内存、CPU 故障;几乎所有表明违反访问保护的内容。