113
\$\begingroup\$

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

\$\endgroup\$
2
  • 50
    \$\begingroup\$ Wow. Possibly the shortest successful question. \$\endgroup\$ Feb 9, 2017 at 11:42
  • 5
    \$\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\$ Nov 21, 2020 at 20:38

79 Answers 79

1 2
3
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\$
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\$ 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\$ 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\$ 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\$ 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
\$\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\$

AArch64, 4 bytes

Raw machine code:

d65f03e0

Disassembly

        .globl f
f:
        ret     xzr

Branches to the xzr register, which is always null. We can't do something like str x0, [xzr] because it would be treated as sp.

\$\endgroup\$
1
\$\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\$ Dec 25, 2020 at 21:18
  • \$\begingroup\$ It works with GFortran, here’s 17 bytes \$\endgroup\$
    – roblogic
    Dec 26, 2020 at 22:00
1
\$\begingroup\$

Nim, 20 bytes

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

Try it online!

Nim, 20 bytes

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

Try it online!

\$\endgroup\$
1
\$\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\$
1
\$\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\$
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\$
    – tsh
    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\$

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
New contributor
ryburger is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\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\$

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\$
    – Sampersand
    Jun 17, 2021 at 2:25
  • \$\begingroup\$ Never said it wasn't. There are actually a lot of interpreters like this. \$\endgroup\$
    – EasyasPi
    Jun 17, 2021 at 2:28
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.