| Bytes | Lang | Time | Link |
|---|---|---|---|
| 011 | Swift 6.1.2 | 250618T194701Z | macOSist |
| 018 | Nim | 210111T200020Z | Adam |
| 003 | x86 and x86_64 machine language | 170214T073811Z | ceilingc |
| 043 | Lua LuaJIT | 170215T040440Z | ceilingc |
| 053 | Python | 240218T210057Z | RuRo |
| 014 | Python 3.8 | 231116T074801Z | dingledo |
| 006 | GFortran | 230822T133448Z | stasoid |
| 015 | C gcc | 230822T122919Z | The Empt |
| 001 | Trilangle | 230223T135436Z | Bbrk24 |
| 014 | Assembly MIPS | 221107T170222Z | EasyasPi |
| 172 | Java 17 OpenJDK | 220702T171349Z | burgerdu |
| 010 | Ruby 3.x | 220122T035917Z | Sisyphus |
| 006 | Squire commit 93d3bf1 | 210617T015826Z | EasyasPi |
| 000 | Knight C/golf | 210522T213524Z | EasyasPi |
| 287 | .mmo MMIX executable | 210519T234057Z | NoLonger |
| 082 | MMIX | 210519T235143Z | NoLonger |
| 054 | Pascal FPC | 210519T201650Z | sech1p |
| 033 | Erlang | 210305T151314Z | Hynek -P |
| 017 | Rust | 210211T012040Z | SuperPiz |
| 002 | Bitwise | 210210T203945Z | EasyasPi |
| 002 | Phooey | 210119T030557Z | EasyasPi |
| 938 | Braille reference interpreter bug | 210118T230524Z | EasyasPi |
| 001 | pbrain | 210111T220612Z | EasyasPi |
| 028 | C++ clang | 210105T054556Z | EasyasPi |
| 027 | F95 | 201225T202126Z | Sapphire |
| 004 | AArch64 | 201226T060353Z | EasyasPi |
| 026 | Zig | 201210T001232Z | Sapphire |
| 003 | NASM | 200122T015426Z | Sapphire |
| 047 | Python 3.8+ | 201209T051003Z | Retr0id |
| 002 | Jelly | 201121T060406Z | Unrelate |
| 033 | Rust | 201121T001828Z | ZippyMag |
| 001 | x86 machine code | 200905T075127Z | Febriyan |
| 012 | x86 assembly intel syntax | 200703T110350Z | Clement |
| 012 | WebAssembly WaWrapper | 200702T060523Z | user9206 |
| 029 | Go | 200623T011347Z | Sapphire |
| 029 | Swift 5 | 200615T234743Z | Sapphire |
| 019 | C++ | 200609T192744Z | Sapphire |
| 062 | C# | 111227T033740Z | captncra |
| 025 | Io | 200328T091642Z | user9206 |
| 3046 | Malbolge | 200327T202331Z | Kamila S |
| 034 | Rust | 180218T135917Z | null |
| 005 | TIBASIC | 190426T134910Z | absolute |
| 002 | x86 .COM | 180407T182833Z | l4m2 |
| 005 | C | 121022T145510Z | null |
| 079 | Common Lisp SBCL | 180903T085358Z | user8220 |
| 009 | Actually | 180901T222701Z | The Fift |
| 015 | Haskell | 180416T230707Z | ბიმო |
| 001 | Assembly Linux | 111226T151430Z | Amol Sha |
| 012 | Clean | 171210T212903Z | Οurous |
| 060 | Tcl | 131120T165101Z | Johannes |
| 057 | Lua 5.3.2 PUCRIO the "official" interpreter | 170218T204024Z | Matcepor |
| 005 | Whispers | 171210T133126Z | caird co |
| 001 | Befunge98 FBBI | 171103T201939Z | James Ho |
| 003 | Forth | 141211T025911Z | Troy Dec |
| 003 | Battlestar | 170614T100318Z | Alexande |
| 223 | Java OpenJDK 9 | 170209T140607Z | Serverfr |
| 048 | Lua luajit | 170214T044508Z | user6213 |
| 015 | Ruby | 170216T082416Z | G B |
| 042 | Dyvil | 170209T101203Z | Clashsof |
| 004 | Bash | 161228T155745Z | zeppelin |
| 003 | Pyth | 161223T011422Z | NO_BOOT_ |
| 014 | C | 161216T112303Z | Charles |
| 022 | Perl 6 | 161215T011232Z | bb94 |
| 007 | JavaScript Shell | 161205T151050Z | Downgoat |
| 039 | F90 | 160325T161622Z | frozar |
| 013 | OCaml | 141207T055036Z | Demi |
| nan | 161125T090212Z | Dennis J | |
| 000 | W32 .com executable | 161121T042335Z | Orion |
| 018 | Unix PDP11 assembly | 151102T182612Z | Random83 |
| 004 | LOLCODE | 151102T155120Z | a spaghe |
| 013 | Python 2 | 151102T012457Z | feersum |
| 002 | brainfuck | 131120T221210Z | Daniel C |
| 006 | J | 130626T194110Z | marinus |
| 004 | PicoLisp | 130626T162047Z | Pierre C |
| 009 | Perl < 5.14 | 121109T233938Z | whio |
| 014 | Cython | 121108T222815Z | boothby |
| 007 | dc | 121026T222739Z | Geoff Re |
| 033 | Python | 121026T212029Z | Daniel |
| 033 | Python | 120118T225906Z | Christop |
| 018 | C | 111228T165729Z | Hasturku |
| 1012 | Perl | 111227T111235Z | Ilmari K |
| 051 | pdfTeX | 111227T073708Z | Bruno Le |
| nan | C 1 chars | 111226T101130Z | Alexande |
| 031 | Haskell | 111226T162106Z | Joey Ada |
| 011 | Bash | 111226T160753Z | Joey Ada |
| 019 | 19 characters in C | 111226T101030Z | saeedn |
Swift 6.1.2, 36 11 bytes
let x:Any=x
Try it on SwiftFiddle! (The Any type annotation is required.)
I'm 99% sure this only works due to a compiler bug, because last time I checked Swift really isn't supposed to let you do this.
Other interesting segfaults (sorted by length)
Stack overflow (13 bytes)
var x:(){x}
x
Declares a computed variable (of type (), aka Void) that accesses itself, then tries to access the variable. (Swift is smart enough to warn you about this. Twice.)
Suicide (22 bytes on Linux, 23 bytes on macOS)
import Glibc
raise(11)
Fairly self-explanatory. Replace Glibc with Darwin if running on macOS.
Deinit abuse (24 bytes)
class C{deinit{C()}}
C()
Try it on Compiler Explorer! (SwiftFiddle doesn't finish backtracing)
This ends up recursively calling _swift_release_dealloc in the runtime, ending with a stack overflow.
"Null" pointer dereference (36 bytes)
UnsafePointer<Any>(bitPattern:1)![0]
Okay, this one's actually kinda wonky.
- If the generic parameter to
UnsafePointerisInt, this doesn't segfault. - But if the whole thing's wrapped in a call to
print, it always segfaults (regardless of the generic parameter). UnsafePointer.init?(bitPattern:)returnsnilfor an argument of0, but if you give it any other value, it will happily return an invalid pointer.
Use-after-free (38 bytes)
[withUnsafePointer(to:{}){$0}][0][0]()
Escapes a pointer to a closure, wraps it in an array to add some indirection, then tries to call the closure via the pointer.
x86 and x86_64 machine language, 3 bytes
0: 50 push %eax
1: eb fd jmp 0
This pushes the value of the EAX (or RAX in long mode) register to the stack in a loop until the stack overflows.
To Try it online!, compile and run the following C program.
const char main[]="\x50\xeb\xfd";
To try it on Windows, prepend the following to mark main as executable.
#pragma section("foo", execute)
__declspec(allocate("foo"))
Lua (LuaJIT), 47 43 bytes
f=require"ffi"f.cdef"int puts()"f.C.puts()
Uses FFI in LuaJIT to call puts() with no (valid) argument.
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 dicts. 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 typemappingproxya = A()is of typeAwe try to execute
m > aorm.__gt__(a)mappingproxydoesn't implement__gt__, so it delegates this call todictthis 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
dis the actual underlying storage of typedict, not the safe/immutable/read-onlymappingproxywrapperwe try to execute
d.__gt__(a)dictdoes implement__gt__, but it doesn't know what to do with our custom typeA, so it returns the specialNotImplementedvaluepython'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
Adoes 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).
Python 3.8, 14 bytes
This only works on Python 3.8 :P. I found this while scavenging bug reports.
*reversed({}),
GFortran, compiler crash, 6 bytes
#if'a'
This answer is more appropriate for Crash your favorite compiler, but that one is closed unfortunately.
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>vL<^e()j!o&rx~2
All of these attempt to perform some operation on an empty stack. Interestingly, , (pop from stack) runs just fine (though it loops forever).
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.
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
publicmodifier 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
varis 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
Ruby 3.x, 10 bytes
->x=(1in^x
Ruby doesn't like a circular pin reference in proc argument for some reason, this results in a null pointer dereference. Since this is a parser bug the program doesn't even have to be syntactically valid.
Squire commit 93d3bf1, 6 bytes
" "*-1
A quite intriguing blunder.
My initial attempt was to allocateth \$\text{II}^\text{LXIV}-\text{I}\$ bytes of memory, but alas, Squire thwarteth me by limiting string lengths to \$\text{XXXII}\$-bit integers, and even my peasant computer with a mere \$\text{VIII}\$ gigabytes of RAM was impervious to said attacks, but lo! Even if malloc rewardeth null, Squire containeth a defense stronger than steel:
void *xmalloc(size_t length) {
void *ptr = malloc(length);
if (ptr == NULL) {
fprintf(stderr, "error allocating %zu bytes of memory\n", length);
// Alas, thwarted again with SIGABRT!
abort();
}
return ptr;
}
Instead, I ventured into value.c and spied this:
case SQ_TSTRING: {
sq_number amnt = sq_value_to_number(rhs);
struct sq_string *result = sq_string_alloc(AS_STRING(lhs)->length * amnt + 1);
// ...
}
As with most strings in C, Squire terminateth all strings with \N, so Sampersand addeth \$I\$ whilst calculating the length.
Intriguingly, \$\text{I} \times -{\text{I}} + \text{I} == \text{N}\$. Therefore, this rewardeth &sq_string_empty.
struct sq_string *sq_string_alloc(unsigned length) {
if (length == 0)
return &sq_string_empty;
// ...
}
To be more swift, Squire containeth some "static" strings for common values like "false" or "".
struct sq_string {
char *ptr;
int refcount;
unsigned length;
bool borrowed;
};
struct sq_string sq_string_empty = {
.ptr = "",
.length = 0,
.refcount = -1,
.borrowed = false,
};
Curiously, we have a string literal treateth as char *, which, despite its mutable appearances, is actually a member of the evil .rodata clan. These sneaky impostors are indistinguishable from normal strings, unless one encanteth -Wwrite-strings.
Returning to value.c, the next line triggers the .rodata impostor:
// Lo! Sampersand hath summoned nasal demons!
*result->ptr = '\0';
In order to make thine computer repent from nasal demons, thy great and powerful Linux exorcises Squire with a SIGSEGV.
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).
.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
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.
Erlang 33
os:cmd("kill -11 "++os:getpid()).
You can invoke like
erl -eval 'os:cmd("kill -11 "++os:getpid()).'
Rust, 17 bytes
fn main(){main()}
Well... This just calls itself.
It may be the only way to do it without unsafe.
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.
Phooey, Interpreter Bug, 2 bytes
<?
This interpreter is so buggy it is beautiful. I can cause a bad free() with one byte of code in two ways. But that, unfortunately, is a SIGABRT. 😂
A quick check of the source code will tell you that the interpreter does not support wrapping. However, the bug isn't "lul I read backwards and it crashes", it is a little more in depth.
The Phooey code translates to these function calls:
< tape.left(1) // move left one cell
? debug() // print debug info
So let's step through it:
First, we call tape.left(1).
void left(int64_t amount) {
right(-amount);
}
This turns into tape.right(-1):
void right(int64_t amount = -1) {
pointer += -1;
Adding -1 to pointer results it being -1, since the initial value was zero.
However, let's double check what type pointer is:
size_t pointer = 0;
size_t furthest = 0;
pointer is a size_t, which is an unsigned type, meaning that this -1 turns into a REALLY big number. Specifically, SIZE_MAX, the largest object size C++ is allowed to handle.
if(pointer > furthest)
furthest = pointer;
We assign pointer to furthest, because SIZE_MAX > 0.
Now, we call debug():
void Phooey::debug() {
std::cout << "Tape: " << tape << std::endl;
}
And this calls the operator overload function for std::ostream << Tape, and here is our bug:
std::ostream& operator<<(std::ostream& stream, Tape& tape) {
for(size_t i = 0; i <= tape.furthest; i++) {
stream << tape[i];
}
}
Let's substitute tape.furthest, if the bug wasn't clear enough:
for(size_t i = 0; i <= SIZE_MAX; i++) {
stream << tape[i];
}
This loop will keep reading data from the tape pointer and printing it, until it segfaults. It is actually an infinite loop otherwise: Since tape.furthest is SIZE_MAX, it will always be true, as SIZE_MAX + 1 == 0.
How ironic that the bug occurs in the debug() function.
A simple way to fix this would be to add wrapping support, making sure that the pointer is always in range. As a matter of fact, almost every bug in this program can be fixed with range checks.
Bonus!
debug() is the buggiest function in this program. It segfaults even without putting any ?s in your code!
<3-509
You may be saying, "How are you calling debug() without ??
And the answer is: ROP. 😂
Specifically, on this exact build of Phooey, the tape is stored on the stack, and cells[-3] contains the return address from call Phooey::run(), 0x403957.
509 bytes before that is just after Phooey::debug() sets up its stack frame. (If I set the pointer to the start of the function, it crashes too early to be interesting since the stack is unaligned). That is why I subtract 509.
It segfaults because it is definitely NOT called how the code expects it to be, and rdi doesn't have the this pointer, so it crashes.
This is OBVIOUSLY going to be dependent on the system and binary itself.
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.
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.
C++ (clang), compiler crash, 36 28 bytes
class{operator*(...){*this*1
Unlike the other compiler crash which I found on my own, I totally didn't look this one up on bugs.llvm.org..
Assembly (as, x64, Linux), 17 10 bytes
Unfortunately, this was not a segfault, but an assertion. Leaving it up with another compiler segfault as a bonus.
I wrote code that raises a SIGSEGV in assembler.
Literally. 😏
Replace \0 with a literal 0x00 byte.
"\0.asciz "
Found this bug when golfing the assembly here
Note that this bug seems to have been fixed as of v2.34.
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.
Zig, 26 bytes
pub fn main()void{main();}
NASM, 3 characters.
any of the following:
ret
nop
cbw
cwd
cdq
clc
cld
cli
cmc
aaa
aas
aad
aam
stc
std
sti
ret causes stack underflow. cli and sti trigger SIGSEGV because they are privileged instructions. All the other opcodes trigger a SIGSEGV simply because there's no exit point.
Python 3.8+, 47 bytes
eval((lambda:0).__code__.replace(co_consts=()))
Not the shortest python entry by far, but this one works without any imports. And as a bonus, this bug is exploitable to get arbitrary code execution, if you're smart about it.
Jelly, 2 bytes
ßß
oh
Since ß isn't actually coded as a recursive function call in the underlying Python, it isn't affected by the recursion limit. I don't actually know how Jelly's quicks work under the hood, but this appears to just create a nested structure that grows until it can't anymore. Any atom or atom-like quick works after the first ß.
Rust, 38 33 bytes
unsafe{*(std::ptr::null_mut())=0}
Full program is fn main(){...}. Segfaults as setting a null pointer to a type is undefined behavior (hence the unsafe block that is required).
Old version:
unsafe{std::ptr::null::<u8>().read();}
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)
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.
Go, 29 characters
package x;func x(y*int){*y=4}
Swift 5, 29 characters:
func x(){y()}
let y={x()}
x()
C++, 19 bytes.
int main(){main();}
Not very interesting, just stack overflow. (pun not intended)
C# - 62
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
C# /unsafe, 23 bytes
unsafe{int i=*(int*)0;}
For some reason I don't understand, *(int*)0=0 just throws a NullReferenceException, while this version gives the proper access violation.
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))
Malbolge, 3046 bytes
Behold, an answer in Malbolge that you can embed inside an answer!
bP&A@?>=<;:9876543210/.-,+*)('&%$T"!~}|;]yxwvutslUSRQ.yx+i)J9edFb4`_^]\yxwRQ)(TSRQ]m!G0KJIyxFvDa%_@?"=<5:98765.-2+*/.-,+*)('&%$#"!~}|utyrqvutsrqjonmPkjihgfedc\DDYAA\>>Y;;V886L5322G//D,,G))>&&A##!7~5:{y7xvuu,10/.-,+*)('&%$#"yb}|{zyxwvutmVqSohmOOjihafeHcEa`YAA\[ZYRW:U7SLKP3NMLK-I,GFED&%%@?>=6;|9y70/4u210/o-n+k)"!gg$#"!x}`{zyxZvYtsrqSoRmlkjLhKfedcEaD_^]\>Z=XWVU7S6QPON0LKDI,GFEDCBA#?"=};438y6543s1r/o-&%*k('&%e#d!~}|^z]xwvuWsVqponPlOjihgIeHcba`B^A\[ZY;W:UTSR4PI2MLKJ,,AFE(&B;:?"~<}{zz165v3s+*/pn,mk)jh&ge#db~a_{^\xwvoXsrqpRnmfkjMKg`_GG\aDB^A?[><X;9U86R53ONM0KJC,+FEDC&A@?!!6||3876w4-tr*/.-&+*)('&%$e"!~}|utyxwvutWlkponmlOjchg`edGba`_XW\?ZYRQVOT7RQPINML/JIHAFEDC&A@?>!<;{98yw5.-ss*/pn,+lj(!~ff{"ca}`^z][wZXtWUqTRnQOkNLhgfIdcFaZ_^A\[Z<XW:U8SRQPOHML/JIHG*ED=%%:?>=~;:{876w43210/(-,+*)('h%$d"ca}|_z\rqYYnsVTpoRPledLLafIGcbE`BXW??TY<:V97S64P31M0.J-+G*(DCB%@?"=<;|98765.3210p.-n+$)i'h%${"!~}|{zyxwvuXVlkpSQmlOjLbafIGcbE`BXW??TY<:V97S64P31M0.J-+G*(D'%A@?"=<}:98y6543,1r/.o,+*)j'&%eez!~a|^tsx[YutWUqjinQOkjMhJ`_dGEaDB^A?[><X;9U86R53O20LKJ-HG*ED'BA@?>7~;:{y7x5.3210q.-n+*)jh&%$#"c~}`{z]rwvutWrkpohmPkjihafI^cba`_^A\[>YXW:UTS5QP3NM0KJ-HGF?D'BA:?>=~;:z8765v32s0/.-nl$#(ig%fd"ca}|_]yrqvYWsVTpSQmPNjMKgJHdGEa`_B]\?ZY<WVUTMR5PO20LK.IHA))>CB%#?87}}49zx6wu3tr0qo-nl*ki'hf$ec!~}`{^yxwvotsrUponQlkMihKIe^]EEZ_B@\?=Y<:V97S64P31M0.J-+GFE(C&A@?8=<;:{876w43s10qo-&%kk"'hf$ec!b`|_]y\ZvYWsVTpSQmlkNiLgf_dcba`C^]\?ZY;WV97SLK33HM0.J-+G*(D'%A$">!};|z8yw543t1r/(-,+*)(i&%fd"!~}|_t]xwvutslqTonmPkjLhKIedGEaZY^A?[Z=X:POT75QP31MFEJ-+**?DC&$@98=~|:{y7xv4us1rp.omll#('&g|#d!~a|{z\\qvuXsUkjoRPOOdihKfH^]bEC_B@\?=Y<:V97S6433HML/J,BAF)'&&;@?"=}549zxww.32s0p(',+*kj!&g$#d!~`|_]y\ZYYnsrUSohglOMihKfH^]bEC_B@\?=YX;V8NMR53O20L/-I,*FED'&A:#>=~;:z87xv4-,1rp.om+*ki'~}$ec!b`__tyx[vXnmrUSoRPlOMihgJIdcb[D_^A\[=Y<:V97SR5P2HGL/-IH+F(>=B%#?"~<}{9zx6wu3tr0/.on+*)('~g$#d!~`|{^y[qpuXVrqToQgfkNLhKIeHFbEC_B@\?=Y<:V97SRQ43NMLKJIHA*EDCBA#9>=<;{3z165.32+0q.-,+l)(h&ge#db~a_{^\x[YuXVrUSoRPlkjMLaJedGbaCBBW\[><XQPU86R53O20L/-I,*F)'C&$@#!=~|:98yx54-t10q.-m+lj(igff{"!b`|uty\ZvYWsVTpSQmPNjMKgJHdcbED_^]\U>YX;VU7S64PO2M/EDI,*F)'&&;@?"~<549zx6wu3tr0qo-nl*kihh}$#"cb}|{zyxqZutWrqSoRPlkNiKa`eHFbEC_^A\>TSX;9U86R53O20L/-I,*FED'&A@?>=<;:3z76543s+0/.-m%l#('&}${"c~}`{z\x[YuXVUUjonQlNdchKIedGEaZY^A?[><X;9U86R53O20//DIHG*)D=&A@#>=}||387x5u-,1rp.om+lj(igff{"!b}_uty\ZvYWsVTpSQmlkNMhgf_HcbE`_A]@>Z=;W:8T75Q42NM0.JCBG*(D'%A$">!};|zyy0543ts0/.-,%l)(i&%e#"c~`vuz][wZXtWUqTRnmPkMcbgJHdGEaDB^A?[ZY<;VUTSRQPI2MLKJI+AFEDC%;$9>=<5:38y65v32r0qonn%*)jh&}|#dbaav{z][wpotWUqTRnQOkjMKg`_dGEaDB^A?[><X;988MRQP32G0KJ-HG)ED'B$:9>!}||387x5u-,1rp.om+lj(ig%fd"ca}`^z][ZZotsrUTongPNNMhgf_dGbaD_^@\?=Y<:VU86RKJO20L/-,,AFE(C%;:?"~<;|9y105vt21rp.'&+*)ji&%${"c~}|{^yxZvYWsVTpoRPlediLJfIGcFD`CA]@>Z=;W:877LQPO21LKJIB+))(CBA@?8=~;:{87w5vt2sq/pn,+l)i!~%fd"!b}_uty\ZYYnsrUpRhglOMiLJfIGcFD`_^A@[ZYXWPU8SRQ4ONM//DIH+)E>=B%#?"~<}{9zx6wutt+0/pn,%$)jhgg|#"ca}vuz][ZZotsVTpihmPNMMbgfIGc\[`CA@@UZY<:VONSRQ4I2MLKJIH+dv'Ps$_"]~[|YzWxUvStQrOpMnKlIjGhEfCAAyxw`;zLxwpo#F!~joQmPNd<hKJr^GoEm~B@zzy,X;c(s&5QJmNGL.h-yTdEc=`;$LK=m|:FV7Cwe3craq_'J\H)jF&%B0/RQ
Rust, 34 bytes
fn main(){unsafe{*(0 as*mut _)=3}}
Just a null pointer assignment, nothing special here.
As a bonus, 45 44 40 bytes solution not using unsafe. Arguably a bug in a compiler.
#![no_main]#[no_mangle]static main:i8=0;
Main is usually a function ;).
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.
x86 .COM, 2 Bytes
66 61 POPAD
x86 .COM, 5 3 Bytes
A3 FF FF
Write to the segment border
C, 5 characters
main;
It's a variable declaration - int type is implied (feature copied from B language) and 0 is default value. When executed this tries to execute a number (numbers aren't executable), and causes SIGSEGV.
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.
Actually, 17 16 11 10 9 bytes
⌠[]+⌡9!*.
If the above doesn't crash, try increasing the number (multi-digit numbers are specified in Actually with a leading colon)
Crashes the interpreter by exploiting a bug in python involving deeply nested itertools.chain objects, which actually uses to implement the + operator.
Assembly (Linux, x86-64), 1 byte
RET
This code segfaults.
Clean, 19 12 bytes
Start=code{}
Every function always returns something in Clean, including Start. Because we haven't specified the type of Start, the compiler assumes (and it can only assume when you inline ABC) that it takes no arguments. Since it takes no arguments, there's nothing on either stack when the function resolves, and so the runtime tries to evaluate the first node in the spine of a graph with... Zero nodes.
Tcl, 60 bytes
set a a;while {[incr i]<999999999} {set a [list $a]};puts $a
Not short, but crashes with a segfault.
This builds a deeply nested list (each with only one element), and when trying to serialize it, Tcl will crash with a stack overflow.
Lua 5.3.2 PUC-RIO (the "official") interpreter - 57 bytes
local t={}t.__newindex=t local y=setmetatable({},t)y[1]=1
Note: does not work on all machines, and was fixed in Lua 5.3.3.
Befunge-98 (FBBI), 1 byte
=
Try it online! (expand the Debug section to view the segfault)
This only works in the FBBI implementation of Befunge, exploiting a bug in its string handling code. Any attempt to read a string from an empty stack will result in a null pointer dereference. You can achieve the same result with the i (Input File) and o (Output File) instructions, which also expect a string on the stack.
Note that this error wouldn't occur if the stack was simply full of zeros, which in Befunge should be semantically equivalent to an empty stack. For it to crash the stack must be genuinely empty, as is the case on startup.
Forth - 3 characters
0 @
(@ is a fetch)
Battlestar, 3 characters
ret
Test
$ echo ret > main.bts
$ bts main.bts
(segfaults)
Java (OpenJDK 9), 311 227 223 bytes
import sun.misc.*;import java.lang.reflect.*;class M{public static void main(String[]args) throws Exception{Constructor<Unsafe> c=Unsafe.class.getDeclaredConstructor();c.setAccessible(true);c.newInstance().getAddress(0);}}
Ungolfed:
import sun.misc.Unsafe;
import java.lang.reflect.Constructor;
public class SegFault {
public static void main(String[] args) throws Exception {
Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
Unsafe unsafe = unsafeConstructor.newInstance();
System.out.println(unsafe.getAddress(0));
}
}
Saved 84 Bytes thanks to Mistah Figg
Lua (luajit), 52 48 bytes
function f()c=coroutine;c.resume(c.create(f))end
An attempt to compete for the bounty that was recently set on an answer in Lua. This is a function submission (basically because I had to define a function anyway, so not including the code to run it saves bytes). Now with 4 bytes saved due to a suggestion by @ceilingcat to avoid repeating the word coroutine.
The program works by creating infinitely many coroutines, suspending each in turn to create and start the next. The most commonly used Lua interpreter, lua, thought of this case and starts causing coroutine creation to fail after a while. luajit, however, segfaults. (Valgrind reports the issue as a failure to grow the OS-defined stack; this is believable, seeing as one common coroutine implementation gives them each separate parts of the stack.)
Ruby, 15 bytes
eval a='eval a'
Segfaults (Ruby 2.3 on Ubuntu xenial)
Dyvil, 42 bytes
dyvil.reflect.ReflectUtils.UNSAFE.getInt 0
Explanation:
dyvil.reflect.ReflectUtils // qualified type name
.UNSAFE // accesses the static field UNSAFE in class
// dyvil.reflect.ReflectUtils, of type sun.misc.Unsafe
.getInt 0 // calls the method sun.misc.Unsafe.getInt(long),
// which tries to read a 4-byte integer from
// the memory address 0
Bash, 4 bytes
Golfed
. $0
Recursively include the script into itself.
Explained
Recursive "source" (.) operation causes a stack overflow eventually, and as Bash does not integrate with libsigsegv, this results in a SIGSEGV.
Note that this is not a bug, but an expected behavior, as discussed here.
Test
./bang
Segmentation fault (core dumped)
Pyth, 3 characters
j1Z
This would be the part where I explain how I came up with this answer, except I legitimately have no clue. If anyone could explain this for me, I'd be grateful.
Here it is in an online interpreter.
Explanation
jsquares the base and calls itself recursively until the base is at least as large as the number. Since the base is 0, that never happens. With a sufficienly high recursion limit, you get a segfault.
C - 14 chars
Be sure to compile an empty file with cc -nostartfiles c.c
Explanation:
What went wrong is that we treated _start as if it were a C function, and tried to return from it. In reality, it's not a function at all. It's just a symbol in the object file which the linker uses to locate the program's entry point. When our program is invoked, it's invoked directly. If we were to look, we would see that the value on the top of the stack was the number 1, which is certainly very un-address-like. In fact, what is on the stack is our program's argc value. After this comes the elements of the argv array, including the terminating NULL element, followed by the elements of envp. And that's all. There is no return address on the stack.
Perl 6, 22
shell "kill -11 $*PID"
Just shelling to whatever shell you have.
JavaScript Shell, 7 bytes
clear()
Clears absolutely everything, not just the current scope which obviously causes lots of borks which result in JS blowing up and segfaulting
F90 - 39 bytes
real,pointer::p(:)=>null()
p(1)=0.
end
Compilation:
gfortran segv.f90 -o segv
Execution:
./segv
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7FF85FCAE777
#1 0x7FF85FCAED7E
#2 0x7FF85F906D3F
#3 0x40068F in MAIN__ at segv.f90:?
Erreur de segmentation (core dumped)
Materials:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
OCaml, 13 bytes
Obj.magic 0 0
This uses the function Obj.magic, which unsafely coerces any two types. In this case, it coerces 0 (stored as the immediate value 1, due to the tag bit used by the GC) to a function type (stored as a pointer). Thus, it tries to dereference the address 1, and that will of course segfault.
Matlab - Yes it is possible!
In a response to a question of mine, Amro came up with this quirk:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
W32 .com executable - 0 bytes
This will seem weird, but on 32 bit Windows systems, creating and executing an empty .com file may cause a segfault, depending on... something. DOS just accepts it (the 8086 having no memory management, there are no meaningful segments to fault), and 64 bit Windows refuses to run it (x86-64 having no v86 mode to run a .com file in).
Unix PDP-11 assembly, 18 bytes binary, 7 bytes source
(this is becoming a theme with me, maybe because it's the only language I sort of know that no-one else here does.)
inc(r0)
Increments the single byte addressed by the initial value of r0 [which happens to be 05162 according to the simh debugger] as of program start.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
And, as always, the extraneous bytes at the end can be removed with strip.
I made a few attempts to get the source shorter, but always ended up getting either a syntax error or SIGBUS.
LOLCODE, 4 bytes
OBTW
Does not work online, only in the C interpreter.
Python 2, 13
exec'()'*7**6
Windows reports an error code of c00000fd (Stack Overflow) which I would assume is a subtype of segmentation fault.
Thanks to Alex A. and Mego, it is confirmed to cause segmentation faults on Mac and Linux systems as well. Python is the language of choice for portably crashing your programs.
brainfuck (2)
<.
Yes, this is implementation-dependent. SIGSEGV is the likely result from a good compiler.
J (6)
memf 1
memf means free memory, 1 is interpreted as a pointer.
PicoLisp - 4 characters
$ pil
: ('0)
Segmentation fault
This is intended behaviour. As described on their website:
If some programming languages claim to be the "Swiss Army Knife of Programming", then PicoLisp may well be called the "Scalpel of Programming": Sharp, accurate, small and lightweight, but also dangerous in the hand of the inexperienced.
Perl ( < 5.14 ), 9 chars
/(?{??})/
In 5.14 the regex engine was made reentrant so that it could not be crashed in this way, but 5.12 and earlier will segfault if you try this.
Cython, 14
This often comes in handy for debugging purposes.
a=(<int*>0)[0]
dc - 7 chars
[dx0]dx
causes a stack overflow
Python 33
import os
os.kill(os.getpid(),11)
Sending signal 11 (SIGSEGV) in python.
Python, 33 characters
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Source: http://bugs.python.org/issue1215#msg143236
Python, 60 characters
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Source: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup
This is the Python version I'm testing on:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
In general the Python interpreter is hard to crash, but the above is selective abusiveness...
C, 18
main(){raise(11);}
Perl, 10 / 12 chars
A slightly cheatish solution is to shave one char off Joey Adams' bash trick:
kill 11,$$
However, to get a real segfault in Perl, unpack p is the obvious solution:
unpack p,1x8
Technically, this isn't guaranteed to segfault, since the address 0x31313131 (or 0x3131313131313131 on 64-bit systems) just might point to valid address space by chance. But the odds are against it. Also, if perl is ever ported to platforms where pointers are longer than 64 bits, the x8 will need to be increased.
pdfTeX (51)
\def~#1{\meaning}\write0{\expandafter~\string}\bye
This is actually probably a bug, but it is not present in the original TeX, written by Knuth: compiling the code with tex filename.tex instead of pdftex filename.tex does not produce a segfault.
C - 11(19) 7(15) 6(14) 1 chars, AT&T x86 assembler - 8(24) chars
C version is:
*(int*)0=0;
The whole program (not quite ISO-compliant, let's assume it's K&R C) is 19 chars long:
main(){*(int*)0=0;}
Assembler variant:
orl $0,0
The whole program is 24 chars long (just for evaluation, since it's not actually assembler):
main(){asm("orl $0,0");}
EDIT:
A couple of C variants. The first one uses zero-initialization of global pointer variable:
*p;main(){*p=0;}
The second one uses infinite recursion:
main(){main();}
The last variant is the shortest one - 7(15) characters.
EDIT 2:
Invented one more variant which is shorter than any of above - 6(14) chars. It assumes that literal strings are put into a read-only segment.
main(){*""=0;}
EDIT 3:
And my last try - 1 character long:
P
Just compile it like that:
cc -o segv -DP="main(){main();}" segv.c
Haskell, 31
foreign import ccall main::IO()
This produces a segfault when compiled with GHC and run. No extension flags are needed, as the Foreign Function Interface is in the Haskell 2010 standard.
Bash, 11
kill -11 $$
19 characters in C
main(a){*(&a-1)=1;}
It corrupts return address value of main function, so it gets a SIGSEGV on return of main.