Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

Thanks!

like image 371
sebf Avatar asked Mar 14 '11 19:03

sebf


2 Answers

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.

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.

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/__except keywords 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.

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.

like image 194
Hans Passant Avatar answered Oct 02 '22 02:10

Hans Passant


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.

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).

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.

like image 30
Ben Voigt Avatar answered Oct 02 '22 01:10

Ben Voigt