Write the shortest code that raises a Segmentation Fault (SIGSEGV) in any programming language.
-
52\$\begingroup\$ Wow. Possibly the shortest successful question. \$\endgroup\$– Matthew RohCommented 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\$– rydwolfCommented Nov 21, 2020 at 20:38
85 Answers
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
.
-
\$\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
-
pbrain, 1 byte
(
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.
Python, 53 characters
class A:__lt__=lambda s,o:o.clear()or s
vars(A)>A()<0
This is a bit longer than some other solutions, but unlike some other solutions it
- works in modern python versions (tested in 3.7.17, 3.8.17, 3.9.17, 3.10.12, 3.11.8 and 3.12.2)
- doesn't look like it does anything dangerous/suspicious/illegal at first glance
- showcases an actual interpreter crash rather than just explicitly dereferencing null/execing invalid code/etc
Btw, don't report this upstream, this issue is already known and closed as "wontfix" in CPython: https://github.com/python/cpython/issues/88004
Explanation:
The important part is essentially
class A:
def __lt__(self, other):
other.clear()
AnyClass.__dict__ > A()
AnyClass
can be any class (A
in the short version) and vars(A)
is a shorthand for A.__dict__
.
The issue here is that the class __dict__
property is supposed to be of type mappingproxy
that is implemented as thin wrapper around regular dict
s. This special type is supposed to make this dictionary immutable/read-only:
AnyClass.__dict__["foo"] = 0 # TypeError: 'mappingproxy' object does not support item assignment
del AnyClass.__dict__["foo"] # TypeError: 'mappingproxy' object does not support item deletion
AnyClass.__dict__.clear() # AttributeError: 'mappingproxy' object has no attribute 'clear'
However, it's possible to circumvent this protection using python's data model. Specifically, mappingproxy
doesn't reimplement all of the required methods itself, but instead just delegates to the underlying dict
implementation.
So, when we do AnyClass.__dict__ > A()
the following happens:
m = AnyClass.__dict__
is of typemappingproxy
a = A()
is of typeA
we try to execute
m > a
orm.__gt__(a)
mappingproxy
doesn't implement__gt__
, so it delegates this call todict
this essentially does something similar to
# except this isn't a real property so it isn't accessible from pure python d = m.__internal_reference_to_underlying_dict return d.__gt__(a)
where
d
is the actual underlying storage of typedict
, not the safe/immutable/read-onlymappingproxy
wrapperwe try to execute
d.__gt__(a)
dict
does implement__gt__
, but it doesn't know what to do with our custom typeA
, so it returns the specialNotImplemented
valuepython's data model says that when
x.__gt__(y)
(x > y
) returnsNotImplemented
, you should try the swapped versiony.__lt__(x)
(y < x
) before failingwe try to execute
a.__lt__(d)
our custom class
A
does have an implementation for__lt__
that callsclear()
on the "other" object, in this case -d
So with this, we were able to call clear()
on the underlying storage for the class __dict__
that was supposed to be made immutable by exposing it through a mappingproxy
. This breaks some core assumptions that python heavily relies on. After that, it's pretty easy to cause a SEGFAULT by attempting to interact with an instance of AnyClass
(or A
in the minified version).
The use of __lt__
and >
here is not mandatory, this also works with any other paired binary operator (eq
/ne
, add
/radd
, sub
/rsub
, mul
/rmul
, etc).
Battlestar, 3 characters
ret
Test
$ echo ret > main.bts
$ bts main.bts
(segfaults)
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.
-
\$\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
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))
C++, 19 bytes.
int main(){main();}
Not very interesting, just stack overflow. (pun not intended)
Swift 5, 29 characters:
func x(){y()}
let y={x()}
x()
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.
Braille (reference interpreter bug), 9 bytes (3 UTF-8 chars)
⢽⢽⢹
⢽ 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.
Bitwise, interpreter bug, 2 bytes
SL
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.
Erlang 33
os:cmd("kill -11 "++os:getpid()).
You can invoke like
erl -eval 'os:cmd("kill -11 "++os:getpid()).'
-
\$\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\$– tshCommented Sep 28, 2021 at 9:14
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
.
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).
-
\$\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\$– EasyasPiCommented Jun 17, 2021 at 2:28
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
Assembly (MIPS, SPIM), interpreter bug, 15 14 bytes
main:sb$0 f
f:
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.
Trilangle, UB, 1 byte
If you allow undefined behavior that happens to segfault on my machine (Windows 10 on x64), all of the following programs work:
+
-
*
:
%
7
>
v
L
<
^
e
(
)
j
!
o
&
r
x
~
2
All of these attempt to perform some operation on an empty stack. Interestingly, ,
(pop from stack) runs just fine (though it loops forever).
Python 3.8, 14 bytes
This only works on Python 3.8 :P. I found this while scavenging bug reports.
*reversed({}),
.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
-
\$\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 at 23:00
GFortran, compiler crash, 6 bytes
#if'a'
This answer is more appropriate for Crash your favorite compiler, but that one is closed unfortunately.