10 ms·
Why is there a “V” in SIGSEGV Segmentation Fault?
- coldpie 6y agoNever thought of that solution to segfaults before. Great trick for writing bug-free programs, going to go integrate that into all my code now.
- gowld 6y agoThis a standard technique for recovering from a memory violation in a non-critical function. The proper way to handle it is to save any transient data and restart the program.
- mnw21cam 6y agoAnd validate the transient data really carefully when you load it back in.
- Elph0 6y agoDon't forget to also catch other sigs.
- majewsky 6y agoMost of my signal handlers work just fine, but for some reason I cannot get the unit tests for SIGKILL and SIGSTOP green.
- segfaultbuserr 6y agoSome programs catch SIGSEGV and automatically prints out the stack trace and starts a debugger for you.
- sp332 6y agoOn Error Resume Next
- tonyarkles 6y agoThanks for the flashbacks!
- underdeserver 6y agoI still shudder at this.
- bigbizisverywyz 6y agoI still remember getting a support call communicated on to myself and a colleague when we were driving on-route to another client. colleague: "Caller says she's getting an error 'No Resumé' ?!?" us: ... huh?..... it is a document management system, but still ... . time passes . . me: Oh! On Error No Resumé us: much hilarity. No Resumé indeed.
- tonyarkles 6y agoNote that x86 has variable-length instructions, so incrementing RIP by 10 will not, in general, do what you want it to do. The author basically put in a nop slide[1] to ensure that that would work. Buuuuuut I’m pretty sure you could parse ELF debug symbols and effectively calculate the address of the next logical C instruction to execute :D Terrifying but fun! [1] https://en.wikipedia.org/wiki/NOP_slide https://en.wikipedia.org/wiki/NOP_slide
- loeg 6y agoOr decode the x86 stream to find the next instruction. :-) Next C statement is pretty cute, though.
- matja 6y agoInteresting problem - what's the shortest C function that takes a pointer to bytes and returns the length of the x86-64 instruction there? (and how many hours would it take to code it)
- loeg 6y agoStart here and minimize as you see fit: https://intelxed.github.io/ref-manual/group__DEC.html#ga4bef6152f61997a47c4e0fe4327a3254 https://intelxed.github.io/ref-manual/group__DEC.html#ga4bef...
- mhh__ 6y agoThe cheating way is probably to do this https://www.blackhat.com/docs/us-17/thursday/us-17-Domas-Breaking-The-x86-ISA.pdf https://www.blackhat.com/docs/us-17/thursday/us-17-Domas-Bre... (page ~71) i.e. shift across an instruction boundary.
- kccqzy 6y agoPut it on a page boundary. Make sure the next page isn't accessible. Analyze the resulting page fault.
- nilsb 6y ago
- tom_mellior 6y agoYou're joking, but this can be used in a semi-practical way to keep programs alive and mostly functioning, see http://people.csail.mit.edu/rinard/paper/pldi14.pdf http://people.csail.mit.edu/rinard/paper/pldi14.pdf for instance. The idea here is that you catch certain faulting operations and drop/fix them: segfaulting store? ignore! segfaulting read? manufacture a result value of 0, it's usually not too wrong. And by using LD_PRELOAD magic, this can even be retrofitted onto existing applications without changing or recompiling them.
- RMPR 6y agoSignals always seem (at least to me) to be an early implementation of exceptions
- monocasa 6y agoSort of? They're really an implementation of interrupts, but sitting on the kernel/user boundary rather than the hardware/kernel boundary. It's a hold over from when a process was really thought of as closer to a virtualized computer rather than a distinct concept in it's own right. And it's not uncommon for the interrupts managing CPU faults to be called exceptions https://wiki.osdev.org/Exceptions https://wiki.osdev.org/Exceptions , so their nomenclature does converge if you squint hard enough.
- Animats 6y ago"It's not uncommon for the interrupts managing CPU faults to be called exceptions, so their nomenclature does converge..." An interrupt and a CPU exception are different things. UNIX treats them similarly because the PDP-11 did. An interrupt is something outside the CPU wanting to be serviced, like an I/O completion. An interrupt can be deferred during a critical section, which is what "preventing interrupts" does. Some machines direct interrupts to one of many CPUs, so whoever is free can handle I/O. Interrupts have priorities, queuing, and are handled like events on a queue. A hardware exception is the CPU doing something that stops execution. Inaccessible memory - could be the need to page something in from disk, or a program error. The OS has to decide that. Floating point overflow. Divide by zero. An illegal instruction. The CPU can't continue. So exceptions cannot be deferred, even if in a critical section. The CPU that raised the exception must handle the exception; it can't be handled by another CPU. UNIX/Linux signals are rarely used for I/O completions in user space, but that is supported. See "aio".[1] Apparently Oracle uses this. [1] https://man7.org/linux/man-pages/man7/aio.7.html https://man7.org/linux/man-pages/man7/aio.7.html
- fanf2 6y agoThe original Bourne shell trapped SEGV (which it called MEMF) as part of its memory management strategy - https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/fault.c https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd...
- jeffffff 6y agomost modern concurrent copying garbage collectors use memory protection and sigsegv handlers to avoid the need for locking
- chrisseaton 6y agoAlmost all language runtimes trap SEGV for memory management and other services.
- simias 6y agoIf you really just want the program to continue operating on dereferencing NULL pointers (and assuming that a NULL pointer is a pointer to address 0 in the VM, which is a risky assumption to make) you can generally convince the OS to map address 0 to something valid, therefore making the access Just Work. Beyond that there are sometimes very valid reasons for allowing segfaults to occur in certain conditions and catching/patching them. For instance in an emulator's dynamic recompiler you could optimize your generated code by assuming that most memory accesses target the emulated RAM region (generally a reasonable assuption). Then you map the RAM buffer in such a way that if it turns out that the emulated program was actually attempting to access an address outside of RAM a memory fault occurs, which you can then catch and recompile the offending code block with a slower but more comprehensive address decode.
- coldpie 6y ago> If you really just want the program to continue operating on dereferencing NULL pointers you can generally convince the OS to map address 0 to something valid, therefore making the access Just Work. Yeah yeah yeah but this ALSO fixes use-after-free bugs! Really an amazing little trick, I wonder why compilers don't just do it automatically.
- pas 6y agoSee also how the JVM uses sigsegv signals for synchronizing safepoints for multiple threads: https://www.ateam-oracle.com/why-am-i-seeing-sigsegv-when-i-strace-a-java-application-on-linux https://www.ateam-oracle.com/why-am-i-seeing-sigsegv-when-i-...
- miohtama 6y agoThis is the old model made popular by Visual Basic. ON ERROR RESUME NEXT
- nialv7 6y agoYou can even do user-space on-demand paging with segfault handlers. Though there is a more modern solution for this: https://man7.org/linux/man-pages/man2/userfaultfd.2.html https://man7.org/linux/man-pages/man2/userfaultfd.2.html
- mwcampbell 6y agoOn a BBS forum in the 90s, I read some lyrics for a blues song where each verse ended with "segmentation violation -- core dumped blues". Here is what seems to be the definitive version of that song: https://www.netfunny.com/rhf/jokes/92q3/coredb.html https://www.netfunny.com/rhf/jokes/92q3/coredb.html
- thomond 6y agoI always thought the V was actually 5 as System V UNIX. Maybe to denote a change that started in that version.
- waynecochran 6y ago> Long long time ago, computers used to have memory segmentation. If you are using an Intel chip, they still do.
- monocasa 6y agoEh, not really in long mode at least.
- zaarn 6y agoWhile technically the modern 64bit CPUs still support segmentation in 16 and 32bit modes (not very well but it works), in 64bit if you're not setting the segment registers to "everything" you're essentially operating outside supported margins. Some strange things happen if you do that. I don't recall exactly but I don't think segmentation was heavily used after 2000 or so, it doesn't really do a lot for you if you have page tables.
- Erwin 6y agoOne thing the segment registers are still used for are thread local storage (on Linux). So you read data from FS (different per thread) segment but same address, if you've prefixed your variable with __thread. (Having said that, I remember optimizing thread local storage away by explicit pointers some time ago in my code, because it was calling some function to get the address constantly, so maybe there are some subtleties there)
- rkeene2 6y agoFWIW, there was a good LWN article recently on the work to expose FS to userspace control safely
- waynecochran 6y agoI haven't tried this lately, but you get a compiler error if you include <windows.h> and use 'near' and 'far' as variables names (which are holdovers when 'near' and 'far' were keywords for ptrs that supported segmented memory flavors). A lot of old OpenGL code and uses 'hither' and 'yon' for the near and far clipping plane for this reason. :)
- dzsekijo 6y agoWell some aspects are still not clear. If this thing was originally called "segmentation violation", who, when switched to calling it "segmentation fault"? Why we don't get Segmentation violation (core dumped) when this thing fires? Actually "violation" sounds much clearer to me. It's telling me that the code I'm running does something that was not part of the contract. With "fault"... well, it's someone's fault... probably someone else's fault... who knows what happened... ¯\_(ツ)_/¯ I wouldn't be surprised if it was found out to sound smoother to managerial ears.
- monktastic1 6y agoI've always thought of it like a geological fault, where the two sides are misaligned. But this only fits in the case of misaligned memory access, and not in the more general case of accessing illegal locations. There's also the tennis fault. It's a noun corresponding to the adjective "faulty."
- commandlinefan 6y agoWell, it's less intrusive to change the text than to change the constant.
- twic 6y agoThe violation is what the program did. A fault is the handler that runs when the program does something funny. Like with a page fault.
- fsckboy 6y agothis is the right answer. I'd tweak it a little, a fault is an interrupt, in this case a hardware interrupt, and the message prints because there is no handler for it (except the default handler that prints the message and halts the program)
- tankenmate 6y agoThe reason is that the term "fault" is used is because on the PDP range of computers (the first computers to run Unix) when a instruction (op code) fails it creates a "fault". In the case of accessing a segment that no longer exists, or beyond the length of the segment, etc the instruction that tried to execute but failed is said to have "faulted", or suffered a "fault". So an instruction that faults due to a memory segment issue is called a "segment fault" and one that faults due to a memory page issue is called a "page fault". In the case of segment, the name stuck even though almost all modern CPUs have pages rather than segments.
- jdxcode 6y agoI've always read it like Dracula is telling me there was a seg fault: "A seg vault! Muah hah hah hah!"
- arooaroo 6y agoLol. Couldn't resist https://i.redd.it/efmm0153po551.png https://i.redd.it/efmm0153po551.png
- fortran77 6y agoThis didn't really answer the question! However, I've been using Unix since the early 80s and never once wondered about this.
- SomeoneFromCA 6y agoSIGSEG sounds inappropriate in some Turkic languages. Extra V kinda masks the issue.
- ktm5j 6y agoThe author makes a big fuss about the old UNIX documentation using sigseg instead of sigsegv.. but then completely ignores the comment in the same line that does use the word violation
- fred256 6y agoIt's interesting to see all signal names in that early version had six letters (SIGQIT instead of SIGQUIT, even) but SIGPIPE was the exception. Was that one added later? (Also funny how the article says "this is from around 1978" when the date on the listing says May 24 1976)
- adrianmonk 6y agoI don't know the real answer, but I've always assumed it's because there's no way to get the right "I" vowel sound without that trailing "E". Also, when creating abbreviations, it feels weird to create one that is only one letter shorter than the full version.
- cesarb 6y ago> Also, when creating abbreviations, it feels weird to create one that is only one letter shorter than the full version. This is Unix, which gave us the "creat" system call (an abbreviation of "create"). https://man7.org/linux/man-pages/man2/creat.2.html https://man7.org/linux/man-pages/man2/creat.2.html
- rkeene2 6y agoIf it makes you feel any better, the creators of UNIX regrets this. > Ken Thompson was once asked what he would do differently if he were redesigning the UNIX system. His reply: "I'd spell creat with an e."; Kernighan, Brian W.; Pike, Rob (1984). The UNIX programming environment. Prentice-Hall. ISBN 0139376992. OCLC 10269821., p. 204.
- coldcat 6y agoThe C linker of those years only support function names up to 6 characters. That's maybe why the defines try to match their respective function name in 6 char.
- hbosch 6y agoThe shape of a "V" is a fault.
- staycoolboy 6y agoSo much for the "do not change" comments. I love these archaeological digs into Unix history.
- khm 6y agoPrior code is available. Before V4, there were no 'signals' per se; errors were trapped individually with dedicated system calls.
- gcoguiec 6y agoMaybe V like in System V?
- rkeene2 6y agoI started a project similar to the fictional "skip instructions that cause segmentation violations" for SIGILL (illegal instruction) which tried to implement SSE3 replacements on hosts without SSE3. It had two modes: replace the illegal instruction in memory, or handle it in the signal handler: https://github.com/rkeene/sse3-emu https://github.com/rkeene/sse3-emu
- anoncake 6y ago> Was there a "Segmentation Vault?"? It's not that far fetched, there's a Referer header after all.
- necovek 6y agoThe original cited SIGSEG constant definition in the OP still has a "segmentation violation" right there in the comment. Which suggests that "violation" was the norm even then.
- solarkraft 6y agoHuh, this doesn't explain why they added the V.