123
\$\begingroup\$

Write the shortest code that raises a Segmentation Fault (SIGSEGV) in any programming language.

\$\endgroup\$
4
  • 52
    \$\begingroup\$ Wow. Possibly the shortest successful question. \$\endgroup\$ Commented Feb 9, 2017 at 11:42
  • 6
    \$\begingroup\$ @MatthewRoh Out of interest, I made this SEDE query. It looks like there are a few with +10 or higher, but this is the first above +40 \$\endgroup\$ Commented Nov 21, 2020 at 20:38
  • \$\begingroup\$ @MatthewRoh And yet the question could be golfed further. "Raise a SIGSEGV. Code golf." \$\endgroup\$ Commented May 20 at 0:24
  • \$\begingroup\$ @MatthewRoh I now have a new contender :) codegolf.stackexchange.com/questions/281871/output-your-user-id \$\endgroup\$ Commented May 22 at 23:41

86 Answers 86

1 2
3
2
\$\begingroup\$

Common Lisp (SBCL), 79 bytes.

SBCL captures pretty much every exception and signal, but we can cause an "Unhandled memory exception" which is the result of a SIGSEGV. We must tell SBCL to not consider type safety and just add a fixnum to a float, which ends up disastrous.

(defun f(x)(declare (optimize (safety 0))(fixnum x))(the fixnum (1+ x)))(f 0.0) 

My SBCL image errors with:

Unhandled memory fault at #x14. [Condition of type SB-SYS:MEMORY-FAULT-ERROR] 

Evaluating (f '(1 5)) returned a garbage object, then (gc) threw Lisp into the low-level debugger after it tried to GC that object presumably. I don't see the difference in results since it is possible to jump back into Lisp from this state, and I imagine this is 100% platform dependent behavior.

\$\endgroup\$
2
\$\begingroup\$

x86 .COM, 2 Bytes

66 61 POPAD 

x86 .COM, 5 3 Bytes

A3 FF FF 

Write to the segment border

\$\endgroup\$
2
  • \$\begingroup\$ Does that work? I thought that DOS runs in real mode and has no memory protection whatsoever. \$\endgroup\$ Commented Apr 7, 2018 at 19:01
  • \$\begingroup\$ @xfix in real mode segment limits are 0xFFFF \$\endgroup\$ Commented Apr 7, 2018 at 19:03
2
\$\begingroup\$

WebAssembly (WaWrapper), 12 bytes

(func $main) 

Try it online!

\$\endgroup\$
2
\$\begingroup\$

x86 machine code - 1 byte

08048060 <_start>: 8048060: 5c pop esp 

This is change value of address esp into value 0x1, and then raises a SIGSEGV.

 (gdb) disassemble _start Dump of assembler code for function _start: 0x08048060 : pop esp End of assembler dump. (gdb) b *0x08048060 Breakpoint 1 at 0x8048060 (gdb) r Starting program: /home/user/programming/assembly/pop Breakpoint 1, 0x08048060 in _start () (gdb) i r $esp esp 0xbfffed40 0xbfffed40 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x08048061 in ?? () (gdb) i r $esp esp 0x1 0x1 (gdb) 
\$\endgroup\$
2
\$\begingroup\$

Zig, 26 bytes

pub fn main()void{main();} 
\$\endgroup\$
2
\$\begingroup\$

F95, 27 bytes

program a;pointer p;p=0;end 

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Could you provide a link to the language, and preferably a link to someone other users can run your code, such as TryItOnline!? \$\endgroup\$ Commented Dec 25, 2020 at 21:18
  • \$\begingroup\$ It works with GFortran, here’s 17 bytes \$\endgroup\$ Commented Dec 26, 2020 at 22:00
2
\$\begingroup\$

pbrain, 1 byte

( 

Try it online!

This is due to an unchecked error in the interpreter:

// Interpret a container of instructions template<typename It> void interpret(It ii, It eos) { while (ii != eos) { switch (*ii) { // Snip case '(': ++ii; { SourceBlock sourceBlock; while (ii != eos && *ii != ')') { sourceBlock.push_back(*ii); ++ii; } // BUG: eos is not handled here, and when ii is incremented below, // it is GREATER than eos, not triggering the loop condition, // which is if ii is EQUAL to eos, and causing an out of bounds read. // // It should be this: // if (ii == eos) { // throw 5; // raise error in the interpreter // } procedures.insert(std::make_pair(mem[mp], sourceBlock)); } break; } // Snip ++ii; } } 

For a version which doesn't rely on an implementation bug, behold, the world's least interesting segfault: the stack overflow from recursing too much.

(:): 

It does exactly as you might expect, it defines a function and then calls itself recursively.

\$\endgroup\$
2
\$\begingroup\$

Braille (reference interpreter bug), 9 bytes (3 UTF-8 chars)

⢽⢽⢹ 

Try it online!

⢽ data_pointer += 32768 ⢽ data_pointer += 32768 ⢹ data_pointer[15] += shared_storage 

The Braille interpreter does not correctly handle memory allocation.

Specifically, it will only allocate the power of two larger than the program size in Braille opcodes. This supposed data pointer does not have much to work with.

Specifically, this program would allocate 4 bytes of memory. Technically, just one opcode () is enough to write out of bounds (since it is writing 15 bytes past a buffer that is 2 bytes large), but that sadly isn't enough to create a segfault. At least not on TIO.

This code will advance the data pointer 65536 bytes forward, then write to 15 bytes past that.

Since this is outside a 64 KB page boundary, it segfaults.

\$\endgroup\$
2
\$\begingroup\$

Bitwise, interpreter bug, 2 bytes

SL 

Try it online!

Hooray for input validation.

SL expects 3 arguments, but I give it zero.

 for (line = 0; line < lines; line++) { char *t = strdup(s[line]); char *cmd = strtok(t," "); char *arg1 = strtok(NULL," "); char *arg2 = strtok(NULL," "); char *arg3 = strtok(NULL," "); //printf("%s %s %s %s\n",cmd,arg1,arg2,arg3); exec_cmd(cmd,arg1,arg2,arg3); free(t); } 

strtok returns a null pointer since I don't supply the expected arguments, and when it dereferences it, it segfaults.

A rough fix:

int _register(char *index) { if (index == NULL) { fprintf(stderr, "missing argument\n"); exit(1); } // ... 

Note: this also allows you to go past the tape bounds, but the state is a global variable so it isn't very useful for my ACE challenge.

\$\endgroup\$
2
\$\begingroup\$

Assembly (MIPS, SPIM), interpreter bug, 15 14 bytes

main:sb$0 f f: 

Try it online!

Here's a cute one I found by accident.

This attempts to store a byte to the address at label f. This is in the .text section.

SPIM is pretty clever in that writing out of bounds of a section will just grow the section. However, writing to .text is tricky.

SPIM stores instructions in a struct for easier parsing it and debugging, instead of just storing data directly.

CPU/inst.h:57:

/* Representation of an instruction. Store the instruction fields in an overlapping manner similar to the real encoding (but not identical, to speed decoding in C code, as opposed to hardware).. */ typedef struct inst_s { short opcode; union { // Snip } r_t; int32 encoding; imm_expr *expr; char *source_line; } instruction; 

Therefore, to store to .text, SPIM will give it a special treatment in bad_mem_write().

CPU/mem.cpp:395:

void set_mem_byte(mem_addr addr, reg_word value) { data_modified = true; // .data if ((addr >= DATA_BOT) && (addr < data_top)) data_seg_b [addr - DATA_BOT] = (BYTE_TYPE) value; // .stack else if ((addr >= stack_bot) && (addr < STACK_TOP)) stack_seg_b [addr - stack_bot] = (BYTE_TYPE) value; // .data else if ((addr >= K_DATA_BOT) && (addr < k_data_top)) k_data_seg_b [addr - K_DATA_BOT] = (BYTE_TYPE) value; // .text or section out of bounds else bad_mem_write (addr, value, 0); // <-- } 

In bad_mem_write(), SPIM will attempt to splice and recompile the instruction as if you modified the memory directly. CPU/mem.cpp:506:

static void bad_mem_write (mem_addr addr, mem_word value, int mask) { mem_word tmp; if ((addr & mask) != 0) /* Unaligned address fault */ RAISE_EXCEPTION (ExcCode_AdES, CP0_BadVAddr = addr) else if (addr >= TEXT_BOT && addr < text_top) { // For halfword and byte writes, attempt to overwrite part of the instruction. switch (mask) { case 0x0: tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]); #ifdef SPIM_BIGENDIAN tmp = ((tmp & ~(0xff << (8 * (3 - (addr & 0x3))))) | (value & 0xff) << (8 * (3 - (addr & 0x3)))); #else tmp = ((tmp & ~(0xff << (8 * (addr & 0x3)))) | (value & 0xff) << (8 * (addr & 0x3))); #endif break; // ... } // Free instruction if it isn't NULL if (text_seg [(addr - TEXT_BOT) >> 2] != NULL) { free_inst (text_seg[(addr - TEXT_BOT) >> 2]); } // create a new instruction with the encoding text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (tmp); 

But wait a second....

SPIM checks for NULL... CPU/mem.cpp:549:

if (text_seg [(addr - TEXT_BOT) >> 2] != NULL) 

...after it already dereferenced it!

CPU/mem.cpp:519 (after macro expansion)

tmp = text_seg [(addr - TEXT_BOT) >> 2]->encoding; 

And what would cause this instruction to be NULL? If it is not an instruction. And what is at the label f? Nothing, so SPIM dereferences a NULL pointer.

  • -1 byte: Parser abuse

I have submitted a patch fixing this but, but this works on at least 9.1.23 and earlier.

\$\endgroup\$
1
\$\begingroup\$

Battlestar, 3 characters

ret 

Test

 $ echo ret > main.bts $ bts main.bts (segfaults) 
\$\endgroup\$
1
\$\begingroup\$

TI-BASIC, 5 bytes

Archive A:A 

Archives the variable A and then tries to get the value of A.
Throws the ERR:ARCHIVED error when used.

This is the closest thing you'd get to a segmentation fault in TI-BASIC, since archived data cannot be accessed directly.

In other words, the software has attempted to access a restricted area of memory.


Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

\$\endgroup\$
4
  • \$\begingroup\$ It's not a segmentation fault. \$\endgroup\$ Commented Jun 11, 2020 at 14:45
  • \$\begingroup\$ @Sapphire_Brick It most definitely is. "A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system)." (source) Archived data can't be accessed in TI-BASIC, simple as that. Do your research before commenting next time. \$\endgroup\$ Commented Jun 17, 2020 at 0:53
  • \$\begingroup\$ You seem to be saying "Fish can swim; I can swim, so I am a fish.". A segmentation fault is more specific than the definition you gave. It has to be the signal SIGSEGV, not just any memory permission error. Suppose you try to use a bash command that you don't have permission to use. Is that a segmentation fault? Of course not. \$\endgroup\$ Commented Jun 17, 2020 at 1:06
  • \$\begingroup\$ Fair enough. Though, you could've explained that in a way without trying to use a strawman like "Fish can swim; I can swim, so I am a fish." \$\endgroup\$ Commented Jun 17, 2020 at 3:13
1
\$\begingroup\$

Io, 25 bytes

Recursively executing the current file raises a segmentation fault. (You know, the system running Io obviously doesn't implement tail-call optimization.)

doFile(System args at(0)) 

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C++, 19 bytes.

int main(){main();} 

Not very interesting, just stack overflow. (pun not intended)

\$\endgroup\$
1
\$\begingroup\$

Swift 5, 29 characters:

func x(){y()} let y={x()} x() 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 25 bytes \$\endgroup\$ Commented Jul 18, 2023 at 18:31
1
\$\begingroup\$

Go, 29 characters

package x;func x(y*int){*y=4} 
\$\endgroup\$
1
\$\begingroup\$

x86 assembly (intel syntax), 12 chars

lgdt [0x123] 

How it works

You force the cpu to load a GDT table at a random address(0x123 in this case) , and of course it'll segfault. And if that location is actually a valid gdt, you should still trigger a GPF. Also, this might triple fault if you use it on msdos.

\$\endgroup\$
1
\$\begingroup\$

Erlang 33

os:cmd("kill -11 "++os:getpid()). 

You can invoke like

erl -eval 'os:cmd("kill -11 "++os:getpid()).' 
\$\endgroup\$
1
\$\begingroup\$

Pascal (FPC), 54 bytes

function _(x:int8):int8;begin _(0);end;begin _(0);end. 

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Free Pascal will not do any tail call optimize. So you may use procedure without parameter instead of a function: procedure _;begin _ end;begin _ end. would work the same. \$\endgroup\$ Commented Sep 28, 2021 at 9:14
1
\$\begingroup\$

MMIX, 8 bytes (2 instrs)

00000000: e0fffef5 a5a4ff00 ṭ”“ṫʠƥ”¡ 
sflt SETH $255,#FEF5 STW $164,$255 

Attempting to do anything with any data at a negative address causes a segfault unless you're the OS. I picked trying to store two bytes to a mem-mapped IO device so it'd look cool with jxd.

\$\endgroup\$
1
\$\begingroup\$

Knight (C/golf), 0 bytes

Not that I would call this interpreter golfed...

A program that is empty (or all whitespace) segfaults.

If it is read from an empty file, getdelim() stores NULL into stream... (line 236)

 else getdelim(&stream,&size,'\0',fopen(argv[2],"r")); 

And when the program does an initial scan for non-whitespace... (line 33)

 while(strspn(stream, "\t\n\f\r {}[]():#")) { 

...it dereferences a NULL pointer.

Otherwise, it will increment the stream pointer (line 54)...

 ++stream; 

...recurse into parse() ((line 68)

 func[1] = parse(); 

and give that same strspn() an out of bounds pointer (it might take a few recursions to hit a page fault).

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Ok but that's kinda the point. It's only well defined for valid inputs and everything else is irrelevent ;p \$\endgroup\$ Commented Jun 17, 2021 at 2:25
  • \$\begingroup\$ Never said it wasn't. There are actually a lot of interpreters like this. \$\endgroup\$ Commented Jun 17, 2021 at 2:28
1
\$\begingroup\$

Java 17 (OpenJDK), 180 177 172 bytes

import sun.misc.*;interface A{static void main(String[]a)throws Throwable{var f=Unsafe.class.getDeclaredFields()[0];f.setAccessible(true);((Unsafe)f.get(null)).getInt(0);}} 

This may be JVM dependent, but I think this is the most compact way to do it.

Some strategies used:

  • An interface is used to get rid of the public modifier on the main function
  • A space isn't necessary between the array brackets and the variable name a
  • Throwable is more compact than the full name of the exception that could be thrown
  • var is used (Java 10 and up) instead of Field, also gets rid of an import
  • A direct array access to the declared fields is used (JVM dependent), for hotspot the main Unsafe instance is the first field in the class
  • getInt(0) is used because I'm pretty sure it has the lowest profile of any method that could cause a segfault in Unsafe
  • A wildcard import can be used rather than the explicit type name to cut down on text
\$\endgroup\$
1
\$\begingroup\$

GFortran, compiler crash, 6 bytes

#if'a' 

Try it online!

This answer is more appropriate for Crash your favorite compiler, but that one is closed unfortunately.

\$\endgroup\$
1
\$\begingroup\$

Nim, 20 18 bytes

proc x=x();x() x() 

Try it online!

Nim, 20 bytes

cast[ptr int](4)[]=2 

Try it online!

\$\endgroup\$
0
\$\begingroup\$

.mmo (MMIX executable), 28 bytes (7 tetras)

Doesn't cause emulator segfault, but the program itself does segfault.

Negative addresses are reserved for the OS, and a fault occurs if the protection bit in rK is the same as the high bit of the instruction pointer, which it will be when the OS tries to start this program at the address given to start.

00000000: 98090100 980a00ff 8fe6a7d6 9b16daee Ƭµ¢¡Ƭ½¡”Ɓȧʂẹɓæḷŀ 00000010: 980b0000 00000000 980c0001 Ƭ¿¡¡¡¡¡¡Ƭ€¡¢ 
98090100 lop_pre 1,0 // version 1, 0 tetras 980A00FF lop_post 255 // and immediately jump to postamble 8FE6A7D6 // almost arbitrary address to start at 9B16DAEE // must have high bit set 980B0000 lop_stab 00000000 // no tetras in symtab 980C0001 lop_end 
\$\endgroup\$
0
\$\begingroup\$

C (gcc), 15 bytes

main(){main();} 

So this is why Python has a recursion limit…

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ main(){*""=0;} is one character shorter and is more likely to segfault. The infinite recursion will not segfault if, for example, the compiler optimizes it into a flat loop (tail call optimization). GCC does exactly this if you pass -O2 or higher. The result is an infinite loop rather than a crash. \$\endgroup\$ Commented May 30, 2024 at 23:00
1 2
3

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.