Najkrótszy kod, który wywołuje SIGSEGV

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

Komentarze

  • Wow. Prawdopodobnie najkrótsze zadane pytanie.
  • @MatthewRoh Z zainteresowania wykonałem to zapytanie SEDE. Wygląda na to, że jest kilka z +10 lub wyższą, ale to jest pierwsza powyżej +40

Odpowiedź

C, 5 znaków

main; 

Jest to deklaracja zmiennej – domniemany jest typ int (funkcja skopiowana z Język B) i 0 to wartość domyślna. Po wykonaniu tej próby próba wykonania liczby (liczby nie są wykonywalne) i powoduje, że SIGSEGV .

Wypróbuj online!

Komentarze

  • @Macmade: Właściwie to 0. static zmienne zaczynają się jako 0, a main; to static, ponieważ zadeklarowałem to poza funkcją. c-faq.com/decl/initval.html
  • Kiedy ostatnio grałem w tę rzecz, zorientowałem się, że ' to inny powód segfaulta. Po pierwsze, wywołując main, przeskakujesz do lokalizacji main, a nie do wartości, inną rzeczą jest to, że main to int, to ' znajdują się w .bss, zwykle funkcje znajdują się w .text, kiedy jądro ładuje program elf, tworzy wykonywalną stronę dla .text i niewykonalne dla .bss, więc wywołując main, przeskakujesz do strony, której nie można wykonać, a wykonanie czegoś na takiej stronie jest błąd ochrony.
  • Tak, segfaults w C są prawie domyślne: P
  • main __attribute__((section(".text#")))=0xc3; FTFY (przynajmniej wydaje się, że powraca bez awaria na mojej x86).
  • @jozxyqk Lub krócej, const main=195;. Ciekawe jest to, że ' działa, a celem tego wyzwania w golfa w kodzie było sprawienie, że kod nie działa :).

Odpowiedź

Bash, 11            

kill -11 $$ 

Komentarze

  • Sygnał 11 w 11 znakach. Wydaje się słuszne.
  • @ nyuszika7h Chciałem zagłosować za twoim komentarzem, ale masz teraz 11 głosów za, więc ' zostawię to na tym. : P
  • @AlexL. wydaje się, że inni ludzie to zepsuli 🙁
  • @theonlygusti Yeah … To ' jest bardzo złe. 🙁 No cóż, mogę teraz zagłosować za .
  • Do 42 głosów za, nie ma sprawy!

Odpowiedz

Assembly (Linux , x86-64), 1 bajt

RET 

Ten kod jest uszkodzony.

Komentarze

  • Jako plik MSDOS .com działa i kończy się bez błędu.
  • Chodzi mi o to: samo określenie „assembly” nie jest ' t wystarczające, aby uczyń to segfault.
  • @JB: W systemie MS DOS żaden program nigdy nie spowoduje błędu segmentacji. To ' s, ponieważ MS DOS działa w trybie rzeczywistym, w którym ochrona pamięci nie istnieje.
  • @celtschk IIRC NTVDM będzie działać na nieistniejących adresach i tych, które nie są przydzielone do MS-DOS.
  • @celtschk: i tak możesz go segfaultować w ten sposób: mov bx, 1000h; shr ebx, 4; mov eax, [ebx] – > Zwiększenie CPU to podstawowy SEGV (AFAIK tam ' nie ma nikogo, kto by się tym zajął).

Odpowiedź

Python 2, 13

exec"()"*7**6 

Windows zgłasza kod błędu c00000fd (przepełnienie stosu), który, jak przypuszczam, jest podtypem błąd segmentacji.

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

Komentarze

  • Segmentation fault: 11 na Macu
  • Segmentation fault (core dumped) w Linuksie
  • Czy to się najpierw rozłącza?
  • @MegaMan Jak na zakończenie zajmuje dużo czasu ? Nie, 7 ** 6 to tylko około 100 KB, więc ' nie ma zauważalnego opóźnienia.
  • @MaxGasner Spróbuj ponownie przeczytać język programowania 🙂

Odpowiedz

pdfTeX ( 51)

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

W rzeczywistości jest to prawdopodobnie błąd , ale nie występuje w oryginalny TeX, napisany przez Knutha: kompilacja kodu z tex filename.tex zamiast pdftex filename.tex nie powoduje segfaulta.

Odpowiedź

LOLCODE, 4 bajty

OBTW 

Nie działa tylko online w interpretatorze języka C.

Komentarze

  • LOL FANCY CODE M8 8/8 KTHXBYE

Odpowiedź

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 n I „m testuję na:

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

Ogólnie rzecz biorąc, interpreter Pythona jest trudny do zawieszenia, ale powyższe jest selektywnym nadużyciem …

Odpowiedź

Dalej – 3 znaki

0 @ 

(@ to pobieranie)

Komentarze

  • Najkrótszy jak dotąd, który będzie działał na nowoczesnych systemach.
  • Który Forth? Gforth po prostu mówi ” Nieprawidłowy adres pamięci ”

Odpowiedź

Plik wykonywalny W32 .com – 0 bajtów

Wydaje się to dziwne, ale w 32-bitowych systemach Windows utworzenie i wykonanie pustego pliku .com może powoduje segfault, w zależności od … czegoś. DOS po prostu to akceptuje (8086 nie ma zarządzania pamięcią, nie ma żadnych znaczących segmentów do błędu), a 64-bitowy system Windows odmawia uruchomienia (x86-64 nie ma trybu v86, aby uruchomić plik .com).

Odpowiedź

C, 18

main(){raise(11);} 

Komentarze

  • czy musisz dodać #include < signal.h > na liście kodu?
  • @FlorianCastellane: w C90 i niższych, dla każdego wywołania funkcji wykonanego bez widocznej deklaracji, kompilator niejawnie deklaruje ją jako int func(). tj. funkcja zwracająca int, pobierająca nieokreślone parametry. W tym przypadku raise jest funkcją zwracającą int, pobierającą argument int, więc to działa (nawet jeśli kompilator narzeka).
  • @Hasturkun main(){main();}

Odpowiedź

Perl (< 5.14), 9 znaków

/(?{??})/ 

W 5.14 silnik regex został ponownie wprowadzony, więc nie można go rozbić w ten sposób, ale 5.12 i jeśli spróbujesz tego wcześniej, wystąpi błąd.

Komentarze

  • Mogę to odtworzyć na Perl 5.14 (Debian) i 5.18 (Arch Linux). sprunge.us/RKHT
  • Powielono za pomocą Perla v5.20.2 (windows)
  • Co z /(?R)/ w starszych wersjach Perla?

Odpowiedź

brainfuck (2)

<. 

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

Komentarze

  • W jaki sposób kompilator powoduje błędy w tym ” dobrze „? To < nie powinno przynieść żadnego efektu lub zawinąć.
  • Natychmiastowe wygenerowanie błędu w czasie wykonywania przy naruszeniu granic jest najlepsze, ponieważ pozwala programistom znaleźć i naprawić błąd tak szybko, jak to możliwe. Pozwolenie błędnemu programowi na działanie przez chwilę i przypadkowe uszkodzenie pamięci przed awarią sprawia, że problem jest trudniejszy do zdiagnozowania. Najgorsze jest całkowite zapobieżenie awarii, jak sugerujesz; programista może pobrać program ” działający „, a następnie zostać publicznie upokorzony, gdy zawiesi się na standardowych kompilatorach i interpreterach.
  • Odwrotnie, wychwytywanie przekroczeń granic przed uruchomieniem nie jest generalnie możliwe ani szczególnie przydatne w przypadkach, w których jest to możliwe. Stworzenie bardziej opisowego błędu w czasie wykonywania byłoby w porządku, ale wychwycenie go przez system operacyjny jako segfault jest świetne, ponieważ nie ' nie ma żadnego wpływu na szybkość. (W przypadku, gdy ' nie jest jasne, sam kompilator nie ' t segfault – tworzy pliki wykonywalne, które rozdzielają się, gdy tylko spróbują aby uzyskać dostęp do pamięci poza granicami.)
  • Czy możesz zapewnić implementację, która powoduje takie zachowanie i została utworzona przed wysłaniem tego wyzwania? Jeśli nie, ta odpowiedź jest nieprawidłowa.
  • Kontrole granic są specyficzne dla implementacji, więc ' m jestem pewien, że są jakieś błędy.Ale 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ć posiadanie przestrzeni do powiększania po obu stronach.

Odpowiedź

Haskell, 31

foreign import ccall main::IO() 

Po skompilowaniu z GHC i uruchomieniu powoduje to segfault. Nie są potrzebne żadne flagi rozszerzeń, ponieważ interfejs funkcji obcych jest w standardzie Haskell 2010.

Komentarze

  • Awwww. Miałem opublikować import Foreign;main=peek nullPtr::IO Int, ale ' s 40.

Odpowiedź

Bash, 4 bajty

Gra w golfa

 . $0  

Rekursywnie włączaj skrypt do siebie.

Wyjaśnione

Rekursywne ” źródło ” (.) operacja powoduje w końcu przepełnienie stosu, a ponieważ Bash nie integruje się z libsigsegv , skutkuje to SIGSEGV.

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

Przetestuj

 ./bang Segmentation fault (core dumped)  

Wypróbuj online!

Odpowiedz

Python 33

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

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

Komentarze

  • Również 33 znaki: from os import* i kill(getpid(),11)

Odpowiedź

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

Wersja C to:

*(int*)0=0; 

Cały program (nie całkiem ISO -zgodne, załóżmy, że to K & RC) ma 19 znaków:

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

Asembler wariant:

orl $0,0 

Cały program ma 24 znaki (tylko do oceny, ponieważ w rzeczywistości nie jest to asembler):

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

EDYTUJ :

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

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

Druga używa nieskończonej rekurencji:

main(){main();} 

Ostatni wariant to najkrótszy – 7 (15) znaków.

EDYCJA 2 :

Wynalazłem 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 znak:

P 

Po prostu skompiluj to w ten sposób :

cc -o segv -DP="main(){main();}" segv.c 

Komentarze

  • w języku C isn ' t main; tylko 5 znaków
  • : Linker nie ' t sprawdza, czy main jest funkcją, czy nie. Po prostu przekazuje go do moduł ładujący i zwraca sigsegv
  • @FUZxxl W tym przypadku main jest zainicjowaną przez zero globalną zmienną typu int, więc otrzymujemy wynik próby wykonania kilku bajtów zerowych. W x86 ' d będzie czymś w rodzaju add %al,(%rax), co jest całkowicie poprawną instrukcją, która próbuje dotrzeć do pamięci pod adresem przechowywanym w . Szanse na dobry adres są minimalne.
  • Oczywiście ostatni wpis może być użyty do wszystkiego, wystarczy podać odpowiednie argumenty kompilatora. Co powinno uczynić go automatycznym zwycięzcą dowolnego konkursu w golfa kodowego. 🙂
  • Zazwyczaj flagi kompilatora inne niż te, które wybierają wersję językową do użycia, są wliczane do całości.

Odpowiedź

Perl, 10/12 znaków

Nieco oszukańczym rozwiązaniem jest zgolenie jednego znaku Joey Adams „trick bash :

kill 11,$$ 

Jednak aby uzyskać prawdziwy błąd w Perlu, unpack p jest oczywistym rozwiązaniem :

unpack p,1x8 

Technicznie nie jest to gwarantowane segfault, ponieważ adres 0x31313131 (lub 0x3131313131313131 w systemach 64-bitowych) może po prostu wskazywać na prawidłową przestrzeń adresową przez przypadek. Ale szanse są przeciwko temu. Ponadto, jeśli perl zostanie kiedykolwiek przeniesiony na platformy, na których wskaźniki są dłuższe niż 64 bity, x8 będzie musiało zostać zwiększone.

Komentarze

  • Co to jest 1x8?
  • @HannesKarppila It ' to krótka droga do pisania "11111111".

Odpowiedź

dc – 7 znaków

[dx0]dx 

powoduje przepełnienie stosu

Komentarze

  • Czy to działa, ale czy możesz to rozwinąć? Dlaczego tak się zachowuje?
  • [dx0] przechowuje dx0 na stosie, a następnie d powiela element górnego stosu, a następnie x zdejmuje element z górnego stosu (dx0) i wykonuje go. Co powiela element na górnym stosie i zaczyna go wykonywać … 0 musi tam być, aby nie było to wywołanie końcowe, więc wszystkie się gromadzą.

Odpowiedź

PicoLisp – 4 znaki

$ pil : ("0) Segmentation fault 

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

Jeśli niektóre języki programowania twierdzą, że są „szwajcarskim scyzorykiem programowania”, PicoLisp można nazwać „Skalpelem of Programming ”: Ostry, dokładny, mały i lekki, ale także niebezpieczny w rękach niedoświadczonych.

Odpowiedź

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 

Komentarze

  • Ładny pierwszy post.

Odpowiedź

Właściwie , 17 16 11 10 9 bajtów

⌠[]+⌡9!*. 

Wypróbuj online!

Jeśli powyższe nie „nie ulegnie awarii, spróbuj zwiększyć liczbę (liczby wielocyfrowe są określone w” Właściwie z początkowym dwukropkiem )

Niszczy interpretację r wykorzystując błąd w Pythonie obejmujący głęboko zagnieżdżone obiekty itertools.chain, które faktycznie używają do implementacji .

Odpowiedź

OCaml, 13 bajtów

Obj.magic 0 0 

Używa funkcji Obj.magic, która w niebezpieczny sposób wymusza dwa dowolne typy. W tym przypadku przekształca 0 (przechowywaną jako bezpośrednia wartość 1, ze względu na bit znacznika używany przez GC) do typu funkcji (przechowywanej jako wskaźnik). W związku z tym próbuje wyłowić adres 1, co oczywiście spowoduje segfault.

Komentarze

  • it coerces 0 (stored as the immediate value 1) – dlaczego 0 jest przechowywane jako 1?
  • @Skyler patrz edycja
  • Obj.magic()0 jest o jeden znak krótszy 🙂

Odpowiedź

Pyth, 3 znaki

j1Z 

To będzie ta część, w której wyjaśnię, jak wymyśliłem tę odpowiedź, z wyjątkiem tego, że zgodnie z prawem nie mam pojęcia . Byłbym wdzięczny, gdyby ktokolwiek mógł mi to wyjaśnić.

Tutaj jest w tłumaczu online.

Wyjaśnienie

j do kwadratu podstawa i wywołuje się rekurencyjnie, aż podstawa będzie co najmniej tak duża jak liczba. Ponieważ podstawa jest 0 , nigdy się nie zdarza. Przy wystarczająco wysokim limicie rekursji pojawia się błąd segregacji.

Dennis ♦

Komentarze

  • Coś wymyśliłem! Przeglądając źródła Pytha ', stwierdziłem, że ten kod j na 1 i 0, który próbuje przekształcić 1 w podstawowy 0. Dlaczego tak się dzieje, nie mam pomysł …
  • Zobacz tutaj . j podnosi do kwadratu podstawę i wywołuje siebie rekurencyjnie, aż podstawa będzie co najmniej tak duża, jak liczba. Ponieważ podstawą jest 0 , to się nigdy nie zdarza. Przy wystarczająco wysokim limicie rekurencji otrzymujesz segfault.
  • @Dennis IDEone
  • @SeeRhino Interpreter Pytha ustawia limit rekursji na 100 000. Przynajmniej w TIO to ' wystarcza na awarię.

Odpowiedź

C # – 62

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

C # / unsafe, 23 bajty

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

Z jakiegoś powodu nie rozumiem, *(int*)0=0 po prostu zgłasza wyjątek NullReferenceException, podczas gdy ta wersja zapewnia prawidłowe naruszenie zasad dostępu.

Komentarze

  • int i=*(int*)0; zwraca dla mnie wyjątek NullReferenceException.
  • Możesz spróbować uzyskać dostęp do wykluczonej lokalizacji, takiej jak *(int*)-1=0 i uzyskać naruszenie zasad dostępu.
  • Konkretnym wyjątkiem jest właśnie to, co clr otacza go i jest nieistotny. Sam system operacyjny w rzeczywistości powoduje błąd seg. We wszystkich tych przypadkach.
  • Przyczyną, dla której *(int*)0=0 zgłasza wyjątek, jest prawdopodobnie optymalizacja. W szczególności, aby uniknąć kosztów sprawdzania null, optymalizator może usunąć sprawdzenia zerowe, ale w przypadku wystąpienia błędu może ponownie zgłosić go jako prawidłowy NullReferenceException.

Odpowiedź

19 znaków w C

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

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

Komentarze

  • Zależy to od układu ramki stosu, więc w niektórych architekturach może nie zawieść.
  • Dlaczego nie po prostu main; lub main(){*""=0;}?
  • @Sapphire_Brick main; jest już podany w innej odpowiedzi.
  • @saeedn To po co w ogóle publikować? To nie jest ' nie drugie od najkrótszego!
  • @Sapphire_Brick W czasie, gdy publikowałem mój, main; nie został ' opublikowany i nie ' nie wiedziałem, że to działa. Zwracałem tylko uwagę, że jest już podane i nie ma sensu zmieniać mojej odpowiedzi. Co więcej, ludzie tutaj ' nie publikują tylko w najkrótszym czasie, czasami interesujący jest również inny sposób rozwiązania problemu.

Odpowiedź

Cython, 14

Często przydaje się przy debugowaniu.

a=(<int*>0)[0] 

Odpowiedź

J (6)

memf 1 

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

Komentarze

  • Dlaczego 1 zamiast 0? Czy zwolnienie pustego wskaźnika w J jest legalne?

Odpowiedź

Matlab – Tak, to możliwe!

W odpowiedzi na moje pytanie , Amro wymyślił następujące dziwactwo:

S = struct(); S = setfield(S, {}, "g", {}, 0) 

Komentarze

  • Podaj wersję Matlaba – R2015B (i 2016B także) po prostu zgłasza błąd: Błąd przy użyciu setfield (wiersz 56) Co najmniej jeden indeks jest wymagany.
  • @FlorianCastellane Nie można teraz wypróbować wszystkich wersji, ale potwierdzono, że w niektórych wersjach występuje błąd segfault, najnowsza to 2014b i najwcześniejsza 2012a.

Odpowiedź

C – 14 znaków

Pamiętaj, aby skompilować pusty plik z cc -nostartfiles c.c

Wyjaśnienie:

Nie udało się potraktować _start tak, jakby to była funkcja w C, i próbowałem z niego wrócić. W rzeczywistości nie jest to w ogóle funkcja. To tylko symbol w pliku obiektowym, którego konsolidator używa do zlokalizowania punktu wejścia programu. Kiedy nasz program jest wywoływany, jest wywoływany bezpośrednio. Gdybyśmy spojrzeli, zobaczylibyśmy, że wartość na szczycie stosu była liczbą 1, co z pewnością jest bardzo nieadresowe. W rzeczywistości na stosie znajduje się wartość argc naszego programu. Po tym następuje elementy tablicy argv, w tym kończący element NULL, po którym następują elementy envp. I to wszystko. Na stosie nie ma adresu zwrotnego.

Komentarze

  • I ' m jestem pewien, że musisz zdobyć dodatkowe argumenty
  • Musisz dodać 14 bajtów na specjalną flagę.
  • @ErikGolfer エ リ ッ ク ゴ ル フ ァ ー -nostartfiles to w rzeczywistości 13 bajtów długości 🙂
  • @CharlesPaulet Myślę, że trzeba też policzyć spację.

Odpowiedź

Unix PDP-11 assembler, 18-bajtowe binarne, 7-bajtowe źródło

(to staje się dla mnie tematem, może dlatego, że jest to jedyny język jaki znam, że nie ktoś inny robi.)

inc(r0) 

Zwiększa pojedynczy bajt adresowany o wartość początkową r0 [która jest równa 05162 zgodnie z debugerem simh] na dzień start programu.

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

I jak zawsze, zbędne bajty na końcu można usunąć za pomocą stripa.

Zrobiłem kilka próby skrócenia źródła, ale zawsze kończyło się ge tting albo błąd składni, albo SIGBUS.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *