4 ms·
How does a segmentation fault work under the hood?
- mattiemass 11y agoGood explanation, but a little too light no the details of the signal mechanism itself.
- asveikau 11y agoNot to mention how and why the kernel receives the trap. There is no mention of the words "page table", and it's very light on use of the word "interrupt".
- pjc50 11y agoPage faults are a "trap" rather than an "interrupt", aren't they? In that they're internal to the CPU-MMU system and delivered synchronously. The answer is a good stackexchange answer in that it's about a page long and covers all the key points. It gives a link to "page" for those who want to understand that subsystem. It's not necessary to include a whole computer architecture course.
- DSMan195276 11y agoIt's debatable - 'trap' isn't extremely well defined, it depends on the architecture. For x86 you'd really call it an exception rather then trap (Trap is used for a bit of a different meaning as far as interrupts go). At the end of the day though, with x86 exceptions/traps/interrupts are all handled like an interrupt (With a few differing details in how they are setup), so saying it's "basically an interrupt" is probably fine, at the very least it's close enough for a high-level explanation.
- steveklabnik 11y agoMy understanding is that "interrupt" is the most general term, and "fault," "trap," and "exception" are all various kinds of interrupts with a very unclear set of rules distinguishing them. And of course this is all architecture dependent.
- hacknat 11y agoFault simply means that the TLB has a cache miss and then traps to the OS to handle the miss. "Fault" is a concept of what is happening a "trap" is what happens. Edit: x86 does have a register for defining the location of page tables that it will walk, the it would trap on a miss if the PTE is missing. Idk, if Linux uses this register or not or uses a software defined TLB, or some kind of hybrid approach.
- moyix 11y ago> x86 does have a register for defining the location of page tables that it will walk, the it would trap on a miss if the PTE is missing. Idk, if Linux uses this register or not or uses a software defined TLB, or some kind of hybrid approach. TLB management is done in hardware on x86. TLB misses don't generate exceptions, they just trigger page table walks in hardware, and then if the page table walk fails (e.g. because of a non-present page table entry) it triggers a CPU exception (page fault) that the OS can then handle. Things like MIPS use a software-managed TLB that works roughly as you describe, though.
- deleted 11y ago[deleted]
- hacknat 11y agoIf you read what I wrote you'll see that I said this.
- geofft 11y agoThe kernel receives the trap because the address is either invalid or has the wrong permissions. The exact details of how this could happen are architecture-dependent, and indeed, the UNIX use of the phrase "Segmentation fault" instead of "Page fault" is a holdover from platforms which used segmentation instead of paging. (Windows 9x's "This program has performed an illegal operation" dialog box gave it the much more accurate name of an "invalid page fault"; I think current Windows goes with "access violation".) The CPU doesn't really know about processes. (Some CPUs have features to manage "tasks", but they are not commonly used 1-to-1 with actual processes, largely for efficiency/performance reasons as I understand it.) The OS tells the CPU that any time it hits a page fault, it should start running code at this address with kernel privilege; this configuration itself also requires kernel privilege. Then it drops privileges and jumps to user code. When the user code makes an invalid memory access, the CPU follows the previous configuration about what to do in the case of an error. That runs a kernel function that delivers the signal (which is an entirely UNIX-specific concept).
- deleted 11y ago[deleted]
- asveikau 11y agoI'm amused when HN replies take this sort of lecturing tone and I am already well familiar with the subject matter.
- geofft 11y agoHaha. I wasn't quite sure if you were asking because you were familiar or unfamiliar, but I figured I'd post it anyway for the benefit of other people clicking through the thread (e.g. GP, who sees replies to descendant comments). Don't read it as a reply to you personally :P
- deleted 11y ago[deleted]
- geofft 11y agoA signal is a UNIX-specific way of, well, signalling a process, and possibly killing it. There are a set of signals defined by the OS, e.g. on Linux, see the "Standard signals" list at http://man7.org/linux/man-pages/man7/signal.7.html http://man7.org/linux/man-pages/man7/signal.7.html (aka `man 7 signal`). They're used for all sorts of external inputs to a process that don't come in through standard input. Some demand immediate response, and some don't. If your program doesn't explicitly choose to do anything with a signal, there's a "default disposition" for each signal, either to kill the process (segmentation faults, Ctrl-C, etc.), do nothing (window resized, child process exited), or suspend the process (Ctrl-Z). (Or unsuspend it, in the case of SIGCONT, but SIGCONT is weird.) If you do want to do something with a signal, you can specify a signal handler, which runs asynchronously when a signal is received: in the middle of some code, your program randomly jumps to that handler to deal with the problem. This is the only way to deal with certain conditions like segmentation faults, since there's no way for the program to keep running. But since it could be in the middle of some code, writing signal handlers is extremely tricky because you don't know what the state of the process is. For instance, malloc() usually takes a per-thread lock on the heap: if you were signalled in the middle of an allocation, calling malloc() will deadlock. There are a few other methods of dealing with signals, like sigwaitinfo() or signalfd / kqueue, that don't have this limitation but also can't respond to things like segmentation faults. If you don't have a signal handler, and the default disposition of the signal is to terminate your process, your exit code will contain the signal that killed you. Your parent process can look at this (usually, it's paying attention for the SIGCHLD signal) and print out a message. That's where the "Segmentation fault" message in the shell comes from: it's after the process is already dead, and the shell, the parent process, is looking at whether it exited cleanly or not. By the way, note that if a process hasn't overridden the default signal dispositions, there's no difference between terminating it with Ctrl-C (SIGINT), Ctrl-\ (SIGQUIT), kill (SIGTERM), or kill -9 (SIGKILL). It's just that it's impossible to change the handling of SIGKILL, so that's your option if the process has a termination handler that's not working right. But otherwise, all four of them cause the process to immediately exit—and make the kernel do the same cleanup. (It is this cleanup that can get stuck and cause a process to be unresponsive even to kill -9: it means the process is already as dead as it can be, but the kernel is trying to close file descriptors or unmap memory and got stuck doing that.)
- js2 11y agohttps://en.m.wikipedia.org/wiki/Segmentation_fault https://en.m.wikipedia.org/wiki/Segmentation_fault seems like a much better explanation to me.
- noxToken 11y agoNon-mobile: https://en.wikipedia.org/wiki/Segmentation_fault https://en.wikipedia.org/wiki/Segmentation_fault
- AnimalMuppet 11y agoObligatory XKCD: https://xkcd.com/371/ https://xkcd.com/371/