Najkrótszy kod, który podnosi SIGSEGV

75

Napisz najkrótszy kod, który wywołuje błąd segmentacji (SIGSEGV) w dowolnym języku programowania.

Arya
źródło
30
Łał. Prawdopodobnie najkrótsze udane pytanie.
Matthew Roh

Odpowiedzi:

113

C, 5 znaków

main;

Jest to deklaracja zmiennej - inttyp jest domyślny (funkcja skopiowana z języka B) i 0jest wartością domyślną. Podczas wykonywania próbuje wykonać liczbę (liczby nie są wykonywalne) i powoduje SIGSEGV.

Wypróbuj online!

Konrad Borowski
źródło
5
@Macmade: Właściwie to jest 0. staticzmienne zaczynają się 0i main;static, jak zadeklarowałem, poza funkcją. c-faq.com/decl/initval.html
Konrad Borowski
16
ostatnim razem, gdy bawiłem się tą rzeczą, doszedłem do wniosku, że segfault ma inny powód. Po pierwsze, wywołując main przeskakujesz do lokalizacji main, a nie do wartości, inną rzeczą jest mainint, jest ona zlokalizowana .bss, zwykle funkcje są zlokalizowane .text, kiedy jądro ładuje program elf, tworzy stronę wykonywalną .texti nie -wykonalne .bss, więc wywołując main, przeskakujesz na stronę niewykonywalną, a wykonanie czegoś na takiej stronie jest błędem ochrony.
mniip,
23
Tak, awarie w C są w zasadzie domyślne: P
Paul Draper
1
main __attribute__((section(".text#")))=0xc3;FTFY (przynajmniej wydaje się, że powraca bez awarii na moim x86).
jozxyqk
2
@jozxyqk Albo krótszy const main=195;. Interesujące jest to, że działa, celem tego golfowego wyzwania golfowego było sprawienie, by kod działał nieprawidłowo, a nie działał :).
Konrad Borowski
74

Bash, 11      

kill -11 $$
Joey Adams
źródło
44
Sygnał 11 w 11 znakach. Wydaje się legit.
nyuszika7h
12
@ nyuszika7h Chciałem głosować za twoim komentarzem, ale teraz masz 11 głosów pozytywnych, więc zostawię to w tym miejscu. : P
HyperNeutrino,
3
@AlexL. wydaje się, że inni zepsuli to :(
theonlygusti
2
@ thehelylygusti Tak ... To źle. :( No cóż, więc mogę teraz
głosować
2
Aż do 42 entuzjastów, bez problemów!
seadoggie01
39

Zestaw (Linux, x86-64), 1 bajt

RET

Ten kod nie działa poprawnie.

Amol Sharma
źródło
7
Jako plik MSDOS .com działa i kończy się bezbłędnie.
JB
10
Chodzi mi o to: samo określenie „zestawu” nie wystarczy, aby uczynić go segregującym.
JB
52
@JB: W MS DOS żaden program nigdy nie spowoduje błędu segmentacji. To dlatego, że MS DOS działa w trybie rzeczywistym, w którym ochrona pamięci nie istnieje.
celtschk
1
@celtschk IIRC NTVDM będzie działał na nieistniejących adresach i nieprzypisanych do MS-DOS.
ζ--
2
@celtschk: Możesz segfault to tak czy inaczej: mov bx, 1000h; shr ebx, 4; mov eax, [ebx] -> CPU podnosi bazowy SEGV (AFAIK nie ma jednak nikogo, kto mógłby to obsłużyć).
Joshua,
26

Python 2, 13

exec'()'*7**6

System Windows zgłasza kod błędu c00000fd (przepełnienie stosu), który, jak zakładam, jest podtypem błędu segmentacji.

Dzięki Alex A. i Mego potwierdzono, że powoduje błędy segmentacji również w systemach Mac i Linux. Python jest wybranym językiem do przenośnego zawieszania programów.

feersum
źródło
7
Segmentation fault: 11na Macu
Alex A.
7
Segmentation fault (core dumped)w systemie Linux
Mego
Czy to się najpierw rozłącza?
Mega Man,
1
@MegaMan Jak długo trwa? Nie, 7 ** 6 to tylko około 100 KB, więc nie ma zauważalnego opóźnienia.
feersum
Dlaczego to działa? Nie wydaje się tak w Pythonie 3.6.8 w systemie Mac OS.
Max Gasner
22

pdfTeX (51)

\def~#1{\meaning}\write0{\expandafter~\string}\bye

Jest to prawdopodobnie błąd , ale nie jest obecny w oryginalnym TeX-ie napisanym przez Knutha: kompilacja kodu tex filename.texzamiast pdftex filename.texnie powoduje awarii pliku.

Bruno Le Floch
źródło
21

LOLCODE, 4 bajty

OBTW

Nie działa online, tylko w tłumaczu C.

spaghetto
źródło
24
LOL FANCY CODE M8 8/8 KTHXBYE
Addison Crump
17

Python, 33 znaki

>>> import ctypes;ctypes.string_at(0)
Segmentation fault

Źródło: http://bugs.python.org/issue1215#msg143236

Python, 60 znaków

>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault

Źródło: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup

To jest wersja Pythona, na której testuję:

Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin

Generalnie interpreter Pythona jest trudny do rozbicia, ale powyższe jest selektywną obelgą ...

ChristopheD
źródło
16

Dalej - 3 znaki

0 @

( @jest pobranie)

Talia Troi
źródło
1
Najkrótszy jak dotąd, który będzie działał na nowoczesnych systemach.
Demi
2
Która czwarta? Gforth mówi po prostu „Nieprawidłowy adres pamięci”
kot
15

C, 18

main(){raise(11);}
Hasturkun
źródło
czy musisz dodać #include <signal.h> do listy kodów?
Florian Castellane
5
@FlorianCastellane: w C90 i niższych, dla każdego wywołania funkcji wykonanego bez widocznej deklaracji, kompilator domyślnie deklaruje to jako int func(). tj. funkcja zwracająca int, przyjmująca nieokreślone parametry. W tym przypadku raisefunkcja zwraca int, biorąc argument int, więc to działa (nawet jeśli kompilator narzeka).
Hasturkun
14

Perl (<5,14), 9 znaków

/(?{??})/

W wersji 5.14 silnik regex został ponownie wprowadzony, aby nie można go było rozbić w ten sposób, ale w wersji 5.12 i wcześniejszej nastąpi awaria, jeśli spróbujesz tego.

whio
źródło
Mogę to odtworzyć na Perlu 5.14 (Debian) i 5.18 (Arch Linux). sprunge.us/RKHT
nyuszika7h
Reprodukcja z Perl v5.20.2 (Windows)
Mehi
14

Plik wykonywalny W32 .com - 0 bajtów

Wydaje się to dziwne, ale w 32-bitowych systemach Windows tworzenie i wykonywanie pustego pliku .com może powodować awarie, w zależności od ... czegoś. DOS po prostu akceptuje to (8086 nie ma zarządzania pamięcią, nie ma żadnych znaczących segmentów do uszkodzenia), a 64-bitowy system Windows odmawia uruchomienia (x86-64 nie ma trybu v86 do uruchomienia pliku .com).

Orion
źródło
13

pieprzenie mózgu (2)

<.

Tak, to zależy od implementacji. SIGSEGV jest prawdopodobnie wynikiem dobrego kompilatora.

Daniel Cristofani
źródło
4
W jaki sposób kompilator segreguje ten „dobry”? To nie <powinno mieć żadnego efektu ani się zawijać.
nyuszika7h
12
Najlepszym rozwiązaniem jest natychmiastowe wygenerowanie błędu czasu wykonania w przypadku naruszenia granic, ponieważ pozwala on programistom znaleźć i naprawić błąd tak szybko, jak to możliwe. Pozostawienie błędnego programu na chwilę i przypadkowe uszkodzenie pamięci przed awarią tylko utrudnia diagnozowanie problemu. Najgorsze jest całkowite zapobieganie katastrofie, jak sugerujesz. programista może „uruchomić” program, a następnie zostać publicznie upokorzony, gdy zawiesi się na standardowych kompilatorach i interpretatorach.
Daniel Cristofani,
1
I odwrotnie, łapanie naruszeń granic przed uruchomieniem nie jest ogólnie możliwe, ani szczególnie przydatne w przypadkach, w których jest to możliwe. Bardziej opisowy błąd czasu wykonywania byłby w porządku, ale system operacyjny przechwytuje go jako awarię, jest świetny, ponieważ nie wiąże się z żadnymi kosztami prędkości. (W przypadku, gdy nie jest to jasne, sam kompilator nie segfault - generuje pliki wykonywalne, które segfault, gdy tylko spróbują uzyskać dostęp do pamięci poza granicami.)
Daniel Cristofani,
4
Czy możesz podać implementację, która powoduje takie zachowanie i została utworzona przed opublikowaniem tego wyzwania? Jeśli nie, ta odpowiedź jest nieprawidłowa.
Mego
1
Kontrole graniczne są specyficzne dla implementacji, więc jestem pewien, że są pewne błędy, które mogą na nim wystąpić. Czy jakikolwiek SIGSEGV? Wątpię. Istnieje jednak duża liczba programów, które zależą od zawijania tablicy po lewej stronie. Wygodne może być przechowywanie po obu stronach.
captncraig
12

Haskell, 31

foreign import ccall main::IO()

Powoduje to segfault po skompilowaniu z GHC i uruchomieniu. Flagi rozszerzeń nie są potrzebne, ponieważ interfejs funkcji zagranicznej znajduje się w standardzie Haskell 2010.

Joey Adams
źródło
10

C - 11 (19) 7 (15) 6 (14) 1 znaki, asembler AT&T x86 - 8 (24) znaków

Wersja C to:

*(int*)0=0;

Cały program (niezupełnie zgodny z ISO, załóżmy, że to K&R C) ma 19 znaków:

main(){*(int*)0=0;}

Wariant asemblera:

orl $0,0

Cały program ma 24 znaki (tylko do oceny, ponieważ tak naprawdę nie jest asemblerem):

main(){asm("orl $0,0");}

EDYCJA :

Kilka wariantów C. Pierwszy wykorzystuje zerową inicjalizację globalnej zmiennej wskaźnika:

*p;main(){*p=0;}

Drugi wykorzystuje nieskończoną rekurencję:

main(){main();}

Ostatni wariant jest najkrótszy - 7 (15) znaków.

EDYCJA 2 :

Wymyślił jeszcze jeden wariant, który jest krótszy niż którykolwiek z powyższych - 6 (14) znaków. Zakłada, że ​​dosłowne ciągi znaków są umieszczane w segmencie tylko do odczytu.

main(){*""=0;}

EDYCJA 3 :

I moja ostatnia próba - 1 postać:

P

Po prostu skompiluj to w ten sposób:

cc -o segv -DP="main(){main();}" segv.c
Alexander Bakulin
źródło
3
w C nie jest główny; tylko 5 jednostek
Arya
1
: Linker nie sprawdza, czy main jest funkcją, czy nie. Po prostu przekazuje ją do modułu ładującego i zwraca sigsegv
Arya
1
@FUZxxl W tym przypadku mainjest globalna zmienna int inicjowana zerem, więc otrzymujemy wynik próby wykonania kilku bajtów zerowych. W x86 byłoby to coś w rodzaju add %al,(%rax)całkowicie poprawnej instrukcji, która próbuje dotrzeć do pamięci pod adresem zapisanym w %rax. Szanse na dobry adres są minimalne.
Alexander Bakulin
6
Oczywiście do wszystkiego można użyć ostatniego wpisu, wystarczy podać odpowiednie argumenty kompilatora. Co powinno uczynić go automatycznym zwycięzcą każdego konkursu golfowego z kodem. :-)
celtschk
5
Zazwyczaj flagi kompilatora inne niż te, które wybierają używaną wersję językową, są wliczane do sumy.
Jerry Jeremiah
9

dc - 7 znaków

[dx0]dx

powoduje przepełnienie stosu

Geoff Reedy
źródło
Czy działa, ale czy możesz opracować? Dlaczego tak się zachowuje?
Stéphane Gourichon
2
[dx0]zapisuje dx0na stosie, następnie dduplikuje element górnego stosu, a następnie xwysuwa element górnego stosu ( dx0) i wykonuje go. Który duplikuje element najwyższego stosu i zaczyna go wykonywać ... 0musi tam być, aby zapobiec wywołaniu ogona, więc wszystkie się gromadzą.
Ben Millwood,
8

Perl, 10/12 znaków

Nieco cheatycznym rozwiązaniem jest ogolenie jednego kawałka sztuczki Joey Adamsa :

kill 11,$$

Jednak, aby uzyskać prawdziwy błąd w Perlu, unpack pjest oczywiste rozwiązanie:

unpack p,1x8

Technicznie nie jest to gwarantowane segfault, ponieważ adres 0x31313131 (lub 0x313131313131313131 w systemach 64-bitowych) może przypadkowo wskazywać prawidłową przestrzeń adresową. Ale szanse są przeciwne. Ponadto, jeśli perl jest kiedykolwiek przenoszony na platformy, na których wskaźniki są dłuższe niż 64 bity, x8należy je zwiększyć.

Ilmari Karonen
źródło
1
Co to za 1x8sprawa?
Hannes Karppila,
@HannesKarppila To jest krótki sposób na napisanie"11111111".
Ilmari Karonen
8

Python 33

import os
os.kill(os.getpid(),11)

Wysyłanie sygnału 11 (SIGSEGV) w pythonie.

Daniel
źródło
2
Również 33 znaki: from os import*ikill(getpid(),11)
Timtech
8

OCaml, 13 bajtów

Obj.magic 0 0

Korzysta z funkcji Obj.magic, która niesłusznie wymusza dowolne dwa typy. W tym przypadku wymusza 0 (przechowywany jako bezpośrednia wartość 1, z powodu bitu znacznika używanego przez GC) na typ funkcji (przechowywany jako wskaźnik). W ten sposób próbuje się wyrejestrować adres 1, co oczywiście spowoduje awarię.

Demi
źródło
1
it coerces 0 (stored as the immediate value 1)- dlaczego 0 jest przechowywane jako 1?
Skyler
1
@Skyler patrz edycja
Demi
1
Obj.magic()0jest o jeden char krótszy :)
Ben Millwood,
8

Bash, 4 bajty

Grał w golfa

. $0

Rekurencyjnie dołącz skrypt do siebie.

Wyjaśniono

Rekurencyjna operacja „source” (.) Powoduje ostatecznie przepełnienie stosu, a ponieważ Bash nie integruje się z libsigsegv , skutkuje to SIGSEGV.

Zauważ, że nie jest to błąd, ale oczekiwane zachowanie, jak omówiono tutaj .

Test

./bang 
Segmentation fault (core dumped)

Wypróbuj online!

zepelin
źródło
8

Faktycznie , 17 16 11 10 9 bajtów

⌠[]+⌡9!*.

Wypróbuj online!

Jeśli powyższe nie ulega awarii, spróbuj zwiększyć liczbę (liczby wielocyfrowe są określone w rzeczywistości z wiodącym dwukropkiem)

Zawiesza interpreter, wykorzystując błąd w pythonie dotyczący głęboko zagnieżdżonych itertools.chainobiektów, który faktycznie używa do implementacji +operatora.

pppery
źródło
7

C # - 62

System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);

Edycja: 23

unsafe{int i=*(int*)0;}

Musi się skompilować z / unsafe, aby ten działał. Z jakiegoś powodu nie rozumiem, *(int*)0=0po prostu zgłasza wyjątek NullReferenceException, podczas gdy ta wersja zapewnia prawidłowe naruszenie praw dostępu.

captncraig
źródło
Te int i=*(int*)0;powroty NullReferenceException dla mnie.
Peter Olson,
Możesz spróbować uzyskać dostęp do negatywnej lokalizacji, np *(int*)-1=0. Uzyskać naruszenie zasad dostępu.
Peter Olson,
Szczególnym wyjątkiem jest to, w co owinięty jest clr i jest nieistotny. Sam OS faktycznie powoduje błąd seg we wszystkich tych przypadkach.
captncraig
Przyczyną *(int*)0=0zgłoszenia wyjątku jest prawdopodobnie optymalizacja. W szczególności, aby uniknąć kosztu sprawdzania null, optymalizator może usunąć kontrole zerowe, ale gdy wystąpi awaria, może ponownie go wyrzucić NullReferenceException.
Konrad Borowski,
7

PicoLisp - 4 znaki

$ pil
: ('0)
Segmentation fault

To jest zamierzone zachowanie. Jak opisano na ich stronie internetowej:

Jeśli niektóre języki programowania twierdzą, że są „szwajcarskim wojskowym nożem programistycznym”, to PicoLisp można nazwać „skalpelem programowania”: ostry, dokładny, mały i lekki, ale także niebezpieczny w rękach niedoświadczonego.

Pierre Carrier
źródło
7

F90 - 39 bajtów

real,pointer::p(:)=>null()
p(1)=0.
end

Kompilacja:

gfortran segv.f90 -o segv 

Wykonanie:

./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)

Materiały:

gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Frozar
źródło
1
Niezły pierwszy post.
Rɪᴋᴇʀ
6

19 znaków w C.

main(a){*(&a-1)=1;}

Koryguje wartość adresu zwrotnego funkcji głównej, więc po powrocie otrzymuje SIGSEGV main.

saeedn
źródło
Zależy to od układu ramki stosu, więc w niektórych architekturach może nie zawieść.
Alexander Bakulin
6

J (6)

memf 1

memfoznacza wolną pamięć, 1jest interpretowane jako wskaźnik.

marinus
źródło
5

Cython, 14

Często przydaje się to do celów debugowania.

a=(<int*>0)[0]
boothby
źródło
5

Unix PDP-11, 18 bajtów binarnych, źródło 7 bajtów

(staje się to dla mnie tematem, być może dlatego, że jest to jedyny język, jaki znam, którego nikt inny tutaj nie zna).

inc(r0)

Inkrementuje pojedynczy bajt adresowany przez wartość początkową r0 [która według debuggera simh to 05162] w chwili uruchomienia programu.

0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000

I jak zawsze, zewnętrzne bajty na końcu można usunąć za pomocą paska.

Podjąłem kilka prób skrócenia źródła, ale zawsze otrzymywałem błąd składniowy lub SIGBUS.

Losowo 832
źródło
5

Matlab - Tak, jest to możliwe!

W odpowiedzi na moje pytanie Amro wymyślił to dziwactwo:

S = struct();
S = setfield(S, {}, 'g', {}, 0)
Dennis Jaheruddin
źródło
Proszę podać wersję Matlaba - R2015B (i również 2016B) po prostu zgłasza błąd: Błąd przy użyciu setfield (wiersz 56) Wymagany jest co najmniej jeden indeks.
Florian Castellane
@FlorianCastellane Nie można wypróbować wszystkich wersji teraz, ale potwierdzono, że daje awarię w niektórych wersjach, z których ostatnia to 2014b i najwcześniejsza 2012a.
Dennis Jaheruddin
5

JavaScript Shell, 7 bajtów

clear()

Czyści absolutnie wszystko, nie tylko obecny zakres, co oczywiście powoduje wiele borków, co powoduje wysadzenie JS i uszkodzenie pliku

Downgoat
źródło
Według MDN (document.clear) powinno to zrobić coś tylko w naprawdę starych wersjach Mozilli, a nawet wtedy, co naprawdę zakłóca twoje wrażenia?
tomsmeding,
@tomsmeding to jest window.clear, FF bezpośrednio tego nie ujawnia, to wbudowany spidermonkey
Downgoat
5

Pyth, 3 znaki

j1Z

W tej części wyjaśniam, w jaki sposób wymyśliłem tę odpowiedź, chyba że nie mam żadnych zasad . Gdyby ktokolwiek mógł mi to wyjaśnić, byłbym wdzięczny.

Tutaj jest w tłumaczu online.

Wyjaśnienie

jpodnosi kwadrat do kwadratu i wywołuje się rekurencyjnie, aż baza będzie co najmniej tak duża jak liczba. Ponieważ podstawa wynosi 0 , to nigdy się nie zdarza. Przy dostatecznie wysokim limicie rekurencji otrzymujesz segfault.

- Dennis ♦

NO_BOOT_DEVICE
źródło
Coś wymyśliłem! Przeglądając źródła Pytha odkryłem, że ten kod działa jna 1i 0, który próbuje przekonwertować 1na bazę 0. Skąd ta awaria, nie mam pojęcia ...
NoOneIsHere
1
Zobacz tutaj . jpodnosi kwadrat do kwadratu i wywołuje się rekurencyjnie, aż baza będzie co najmniej tak duża jak liczba. Ponieważ podstawa wynosi 0 , to nigdy się nie zdarza. Przy dostatecznie wysokim limicie rekurencji otrzymujesz segfault.
Dennis,
@Dennis IDEone
NoOneIsHere
@SeeRhino Interpreter Pyth ustawia limit rekurencji na 100 000. Przynajmniej na TIO, to wystarczy na awarię.
Dennis