Segmentation fault protection

From Rosetta Code
Segmentation fault protection is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A segmentation fault or segfault is an error that your computer will raise if a program attempts to access memory that it's not supposed to, for example, trying to write to executable code or read-only memory, dereferencing a null pointer, etc. Often this happens when an array is indexed out-of bounds, such as (for example) trying to read element 500 of an array with only 6 entries (see the pseudocode example below):

myArray = {1,2,3,4,5,6};
myVariable = myArray[500];        //causes a segfault

Although this seems like a silly example, it's a lot more common than those who are new to programming may think, and different languages have different safeguards in place for preventing this kind of thing from happening. Some languages would refuse to compile the above example, some will give you a warning and run anyway, and others may not even care at all.

Task

Showcase what built-in protections your language has for segmentation faults, if any. If your language doesn't have any, show what happens when your program commits a segmentation fault. (Be safe and don't destroy your computer!)


6502 Assembly

The 6502 doesn't have any handlers for access violation; the entire address space of the CPU is fair game. As you can imagine this isn't good for computer security.

However, the stack being fixed at $0100-$01FF means that the stack will never overwrite the heap, yet it can get to the point where new values pushed onto the stack overwrite the old, which can cause a CPU crash if you try to unwind the stack back to the beginning.

The 6502 uses memory-mapping to interact with external hardware, and reading/writing a memory location you normally shouldn't because your array indexed out of bounds can cause issues with external hardware, and even on some systems can result in a killer poke which can damage certain machines such as the Commodore PET. Memory-mapped ports don't work like normal memory; unlike normal memory, even reading a memory-mapped port can affect its contents, or affect the contents of other ports that are related to that hardware. (This isn't a property of the 6502 itself, but of the hardware connected to it.)

Phix

Phix has extensive compilation and runtime error handling, including bounds checking, unassigned variables, invalid assignments, and more, as well as exception handling, and strives to always deliver clear human-readable and actually useful error messages along with the file name and line number where they occurred - of course within reason, as the following example shows messages triggered by inline assembly are inherently always going to be a bit more cryptic than the norm.

try
   #ilASM{ xor eax,eax
           mov eax,[eax]
         }
catch e
    ?e
end try
Output:
{30,10043489,3,21,"-1","e01.exw",`C:\Program Files (x86)\Phix\`,"fatal exception [MEMORY VIOLATION] at #00994061"}

You could, of course, like the non-caught errors do, make that a bit prettier, in fact here is what you get without try/catch:

C:\Program Files (x86)\Phix\e01.exw:3
fatal exception [MEMORY VIOLATION] at #008A9042

Global & Local Variables

--> see C:\Program Files (x86)\Phix\ex.err
Press Enter...

The generated ex.err contains a full callstack and itemises in painstaking detail all variables and their values at the point of failure.

Wren

In theory and barring bugs in the language's implementation Wren code should never segfault. Array bounds are always checked, memory allocation and reclamation is automatic and there is no support for pointers at all.

So the example code below compiles: <lang ecmascript>var myArray = [1,2, 3, 4, 5, 6] var myVariable = myArray[500]</lang> but if you try to run it you get a "Subscript out of bounds" error.

However, when Wren is embedded in a C host, segfaults are certainly possible and there is no protection against them whatsoever. As Wren's virtual machine is not re-entrant a common source of segfaults is trying to treat it as if it was!