Broadly speaking, I am wondering how the kernel (or the CPU) knows that a process has tried to access a memory location for which it lacks permission, and how the mysterious piece of hardware called MMU helps in doing that.
In particular: It seems to me that the MMU is agnostic towards the memory management model of the OS kernel (paging, memory zones, process adress spaces...) (I would presume that Linux and Windows pages are not exactly the same, for example. Correct me if I'm wrong). But then, how does my CPU find out whether the current code may access location x
? And how does it signal this to the kernel?
A segfault occurs when a reference to a variable falls outside the segment where that variable resides, or when a write is attempted to a location that is in a read-only segment.
During the system call, the kernel had a segfault! When this happens to a user-space process, the kernel just sends SIGSEGV to the offending process, which typically kills it (unless the process explicitly handles the signal).
On a Unix operating system such as Linux, a "segmentation violation" (also known as "signal 11", "SIGSEGV", "segmentation fault" or, abbreviated, "sig11" or "segfault") is a signal sent by the kernel to a process when the system has detected that the process was attempting to access a memory address that does not ...
There are four common mistakes that lead to segmentation faults: dereferencing NULL, dereferencing an uninitialized pointer, dereferencing a pointer that has been freed (or deleted, in C++) or that has gone out of scope (in the case of arrays declared in functions), and writing off the end of an array.
This is probably too big a topic to completely answer satisfactorily here; you'll do better to search for some papers/articles/books that discuss the hardware behind virtual memory implementations (probably starting with a specific architecture, since there are significant differences between e.g. x86, x86_64, sparc, etc...).
The short answer, though, is that the hardware handles this through the page tables. Every memory access that the MMU is asked to handle is verified through the page table structures. If the page table entry describing the page containing the address being requested is not marked to allow the type of access being requested (read/write/execute/...), the hardware generates a trap that Linux eventually calls a "segmentation fault". Other OSes name them differently (e.g. general protection fault, ...). The OS kernel then has to figure out the reason for the fault and whether anything can be done about it (many traps are handled by the kernel to swap in new pages from disk, map a new empty page, etc., but some, like null-pointer dereferences, the best thing the kernel can do is throw it at the application to say "you did something bad").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With