Nejkratší kód, který vyvolá SIGSEGV

Napište nejkratší kód, který vyvolá Segmentation Fault (SIGSEGV) v libovolném programovacím jazyce.

Komentáře

  • Páni. Možná nejkratší úspěšná otázka.
  • @MatthewRoh Ze zájmu jsem vytvořil tento dotaz SEDE. Vypadá to, že jich je pár s +10 nebo vyšším, ale toto je první nad +40

Odpověď

C, 5 znaků

main; 

Je to deklarace proměnné – int typ je implicitní (funkce zkopírována z Jazyk B) a 0 je výchozí hodnota. Při spuštění se pokusí provést číslo (čísla nejsou spustitelná) a způsobí SIGSEGV .

Vyzkoušejte online!

Komentáře

  • @Macmade: Ve skutečnosti je to 0. static proměnné začínají jako 0 a main; je static, jak jsem prohlásil mimo funkci. c-faq.com/decl/initval.html
  • když jsem si s touto věcí naposledy hrál, přišel jsem na to, že ‚ je jiný důvod pro segfault. Nejprve voláním main přeskočíte na umístění main, ne na hodnotu, další věc je main je int, to ‚ s umístěn v .bss, obvykle jsou funkce umístěny v .text, když jádro načte program elf, vytvoří spustitelnou stránku pro .text a neproveditelné pro .bss, takže voláním main přejdete na nespustitelnou stránku a provedení něčeho na takové stránce je chyba ochrany.
  • Ano, segfaults v C jsou skoro výchozí: P
  • main __attribute__((section(".text#")))=0xc3; FTFY (alespoň se zdá, že se vrátí bez narazil na můj x86).
  • @jozxyqk Nebo kratší, const main=195;. Jak zajímavé je, že ‚ to funguje, cílem této výzvy golfového kódu bylo udělat kód segfault, nikoli fungovat :).

Odpověď

Bash, 11            

kill -11 $$ 

Komentáře

  • Signál 11 v 11 znacích. Vypadá to, že je to legitimní.
  • @ nyuszika7h Chtěl jsem váš komentář podpořit, ale právě teď máte 11 hlasujících, takže ‚ to nechám tak. : P
  • @AlexL. Zdá se, že to ostatní pokazili 🙁
  • @theonlygusti Jo … To je ‚ příliš špatné. 🙁 No, pak to teď mohu hlasovat. .
  • Až 42 hlasů, žádný kontakt!

Odpověď

Sestava (Linux , x86-64), 1 bajt

RET 

Tento kód segfaults.

Komentáře

  • Jako soubor MSDOS .com se spouští a končí bez chyby.
  • Moje myšlenka je: pouze zadání „assembly“ není ‚ natolik, aby nastavit jako výchozí.
  • @JB: V systému MS DOS žádný program nikdy nevytvoří chybu segmentace. To ‚ s, protože systém MS DOS běží v reálném režimu, kde ochrana paměti neexistuje.
  • @celtschk IIRC NTVDM se bude zobrazovat na neexistujících adresách a těch, které nejsou přiděleny systému MS-DOS.
  • @celtschk: Můžete to stejně nastavit takto: mov bx, 1000h; shr ebx, 4; mov eax, [ebx] – > CPU raise je základním SEGV (AFAIK tam ‚ není nikdo, kdo by to zvládl).

Odpovědět

Python 2, 13

exec"()"*7**6 

Windows hlásí chybový kód c00000fd (Stack Overflow), který bych předpokládal jako podtyp chyba segmentace.

Díky Alexovi A. a Megovi je potvrzeno, že způsobí poruchy segmentace také v systémech Mac a Linux. Python je jazyk volby pro přenosné havárie vašich programů.

Komentáře

  • Segmentation fault: 11 na počítačích Mac
  • Segmentation fault (core dumped) v systému Linux
  • Zavěsí to jako první?
  • @MegaMan Jak dlouho trvá dokončení ? Ne, 7 ** 6 je jen asi 100 kB, takže ‚ není znatelné zpoždění.
  • @MaxGasner Zkuste si znovu přečíst programovací jazyk 🙂

Odpovědět

pdfTeX ( 51)

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

Toto je ve skutečnosti pravděpodobně chyba , ale není v původní TeX, napsaný Knuthem: kompilace kódu s tex filename.tex místo pdftex filename.tex nevytváří segfault.

odpověď

LOLCODE, 4 bajty

OBTW 

nefunguje online, pouze v tlumočníku C.

Komentáře

  • LOL FANCY CODE M8 8/8 KTHXBYE

Odpověď

Python, 33 znaků

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

Zdroj: http://bugs.python.org/issue1215#msg143236

Python, 60 znaků

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

Zdroj: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup

Toto je verze Pythonu n Testuji na:

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

Tlumočník Pythonu se obecně těžko zhroutí, ale výše uvedené je selektivní zneužívání …

Odpověď

Další – 3 znaky

0 @ 

(@ je načítání)

Komentáře

  • Dosud nejkratší, který bude fungovat na moderních systémech.
  • Který dále? Gforth jen říká “ Neplatná adresa paměti “

odpověď

Spustitelný soubor W32 .com – 0 bajtů

To se bude zdát divné, ale na 32bitových systémech Windows může vytvoření a spuštění prázdného souboru .com může způsobit segfault, v závislosti na … něčem. DOS to pouze přijímá (8086 nemá správu paměti, neexistují žádné smysluplné segmenty) a 64bitový Windows jej odmítá spustit (x86-64 bez režimu v86, ve kterém lze spustit soubor .com).

Odpověď

C, 18

main(){raise(11);} 

Komentáře

  • musíte do seznamu kódů přidat #include < signal.h >?
  • @FlorianCastellane: v C90 a nižší, pro jakékoli volání funkce provedené bez viditelné deklarace, kompilátor implicitně deklaruje jako int func(). tj. funkce vracející int s nespecifikovanými parametry. V tomto případě je raise funkce, která vrací int a přijímá argument int, takže to vyjde (i když si kompilátor stěžuje).
  • @Hasturkun main(){main();}

odpověď

Perl (< 5.14), 9 znaků

/(?{??})/ 

V 5.14 byl regex engine reentrantní, takže nemohl být takto havarován, ale 5.12 a dříve se segfault, pokud to zkusíte.

Komentáře

  • Mohu to reprodukovat na Perlu 5.14 (Debian) a 5.18 (Arch Linux). sprunge.us/RKHT
  • Reprodukováno s Perl v5.20.2 (Windows)
  • A co /(?R)/ ve starších verzích Perlu?

odpověď

brainfuck (2)

<. 

Ano, závisí to na implementaci. SIGSEGV je pravděpodobný výsledek dobrého kompilátoru.

Komentáře

  • Jak je na tom kompilátor, který segfaults “ dobrý „? To < by nemělo mít žádný účinek nebo by se mělo zabalit.
  • Okamžité vytvoření chyby běhového modulu při porušení hranic je nejlepší, protože umožňuje programátorovi najít a opravit chybu jako co nejrychleji. Pokud necháte buggy program chvíli běžet a nahodile poškodíte paměť, než dojde k havárii, bude diagnostika problému obtížnější. Úplná prevence havárie, jak navrhujete, je nejhorší; programátor může nechat program “ pracovat “ a poté být veřejně ponížen, když dojde k chybě standardních překladačů a tlumočníků.
  • Naopak, zachytit porušení pravidel před dobou běhu není obecně možné, ani zvlášť užitečné v případech, kdy je to možné. Produkce popisnější chyby za běhu by byla v pořádku, ale nechat ji operačním systémem zachytit jako segfault je skvělé, protože to ‚ nemá žádné náklady na rychlost. (V případě, že to ‚ s není jasné, kompilátor sám o sobě ‚ t segfault – produkuje spustitelné soubory, které segfault, jakmile se pokusí pro přístup k paměti mimo hranice.)
  • Můžete poskytnout implementaci, která produkuje toto chování a byla vytvořena před zveřejněním této výzvy? Pokud ne, tato odpověď je neplatná.
  • Kontroly hranic jsou specifické pro konkrétní implementaci, takže jsem si ‚ jistý, že by se vyskytly chyby, které by se vyskytly.Byl by nějaký SIGSEGV? Pochybuji. Existuje velké množství programů, které závisí na zalomení pole vlevo. Může být docela pohodlné mít na obou stranách rozšiřitelné úložiště.

Odpovědět

Haskell, 31

foreign import ccall main::IO() 

Při kompilaci s GHC a spuštění se vytvoří segfault. Nejsou nutné žádné příznaky rozšíření, protože rozhraní cizích funkcí je ve standardu Haskell 2010.

Komentáře

  • Awwww. Chtěl jsem zveřejnit import Foreign;main=peek nullPtr::IO Int, ale to ‚ s 40.

odpověď

Bash, 4 bajty

golf

 . $0  

Rekurzivně zahrnout skript do sebe.

Vysvětlení

Rekurzivní “ zdroj “ (.) operace nakonec způsobí přetečení zásobníku a protože Bash se neintegruje s libsigsegv , výsledkem je SIGSEGV.

Upozorňujeme, že se nejedná o chybu, ale o očekávané chování, jak je popsáno zde .

Test

 ./bang Segmentation fault (core dumped)  

Vyzkoušejte online!

Odpověď

Python 33

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

Odesílání signálu 11 (SIGSEGV) v pythonu.

Komentáře

  • Také 33 znaků: from os import* a kill(getpid(),11)

odpověď

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

Verze C je:

*(int*)0=0; 

Celý program (ne tak docela ISO -kompatibilní, předpokládejme, že K & RC) je dlouhý 19 znaků:

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

Assembler varianta:

orl $0,0 

Celý program má 24 znaků (pouze pro vyhodnocení, protože to není vlastně assembler):

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

EDIT :

Několik variant C. První používá nulovou inicializaci proměnné globálního ukazatele:

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

Druhý používá nekonečnou rekurzi:

main(){main();} 

Poslední varianta je nejkratší – 7 (15) znaků.

EDIT 2 :

Vynalezl ještě jednu variantu, která je kratší než kterýkoli z výše uvedených – 6 (14) znaků. Předpokládá, že doslovné řetězce jsou vloženy do segmentu jen pro čtení.

main(){*""=0;} 

EDIT 3 :

A můj poslední pokus – 1 znak dlouhý:

P 

Stačí to takto zkompilovat :

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

Komentáře

  • v jazyce C isn ‚ t main; pouze 5 znaků
  • : Linker nekontroluje ‚, zda je main funkční nebo ne. Stačí jej předat zavaděč a návrat sigsegv
  • @FUZxxl V tomto případě je main globální proměnná int s nulovou inicializací, takže to, co dostaneme, je výsledek pokusu o provedení nula bajtů. V x86 to ‚ d může být něco jako add %al,(%rax), což je naprosto platná instrukce, která se snaží dosáhnout paměti na adrese uložené v %rax. Šance na dobrou adresu je minimální.
  • Poslední položku lze samozřejmě použít pro všechno, stačí zadat správné argumenty kompilátoru. Díky tomu by se měl stát automatickým vítězem jakékoli soutěže v golfu kódu. 🙂
  • Příznaky jiných překladačů než ty, které zvolí jazykovou verzi, se obvykle započítávají do součtu.

Odpověď

Perl, 10/12 znaků

Mírně podvádějícím řešením je oholit jeden znak Joey Adams „bash trik :

kill 11,$$ 

Chcete-li však získat skutečný segfault v Perlu, je unpack p zřejmým řešením :

unpack p,1x8 

Technicky to není „zaručeno na segfault, protože adresa 0x31313131 (nebo 0x3131313131313131 na 64bitových systémech) mohl by náhodou ukázat na platný adresní prostor. Ale šance jsou proti. Pokud je perl někdy portován na platformy, kde jsou ukazatele delší než 64 bitů, bude třeba x8 zvýšit.

Komentáře

  • Co je to 1x8?
  • @HannesKarppila ‚ je krátký způsob psaní "11111111".

Odpověď

dc – 7 znaků

[dx0]dx 

způsobí přetečení zásobníku

Komentáře

  • Jsou díla, ale můžete je rozvinout? Proč se tak chová?
  • [dx0] ukládá dx0 do zásobníku a poté d duplikuje prvek horního zásobníku, poté x zobrazí prvek horního zásobníku (dx0) a provede jej. Který duplikuje prvek nejvyššího zásobníku a začne jej spouštět … 0 tam musí být, aby tomu zabránil, aby se to stalo koncovým voláním, takže se všichni hromadí.

Odpověď

PicoLisp – 4 znaky

$ pil : ("0) Segmentation fault 

Toto je zamýšlené chování. Jak je popsáno na jejich webových stránkách:

Pokud některé programovací jazyky tvrdí, že jsou „švýcarským armádním nožem programování“, pak se PicoLisp může nazývat „Skalpel“ of Programming „: Ostré, přesné, malé a lehké, ale také nebezpečné v rukou nezkušených.

Odpovědět

F90 – 39 bajtů

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

Kompilace:

gfortran segv.f90 -o segv 

Provedení:

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

Materiály:

gfortran --version GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 

Komentáře

  • Hezký první příspěvek.

Odpověď

Vlastně , 17 16 11 10 9 bajtů

⌠[]+⌡9!*. 

Vyzkoušejte to online!

Pokud výše uvedená chyba selže, zkuste zvýšit počet (víceciferná čísla jsou uvedena ve skutečnosti s úvodním dvojtečkou )

Havaruje interpret r využitím chyby v pythonu zahrnující hluboce vnořené itertools.chain objekty, které skutečně používají k implementaci + operátor.

Odpověď

OCaml, 13 bajtů

Obj.magic 0 0 

Používá funkci Obj.magic, která nebezpečně vynutí všechny dva typy. V tomto případě vynucuje 0 (uloženo jako okamžitá hodnota 1, kvůli bitu značky použitému GC) na typ funkce (uložen jako ukazatel). Snaží se tedy dereferovat adresu 1, což bude samozřejmě segfault.

Komentáře

  • it coerces 0 (stored as the immediate value 1) – proč je 0 uložena jako 1?
  • @Skyler viz úpravy
  • Obj.magic()0 je o jeden znak kratší 🙂

Odpověď

Pyth, 3 znaky

j1Z 

To by byla část, kde vysvětlím, jak jsem přišel k této odpovědi, kromě toho, že legitimně nemám žádnou stopu . Pokud mi to někdo může vysvětlit, budu vděčný.

Tady je v online tlumočníkovi.

Vysvětlení

j umocní základnu na druhou a rekurzivně se volá, dokud základna není alespoň tak velká jako číslo. Protože základna je 0 , nikdy se nestane. S dostatečně vysokým limitem rekurze získáte segfault.

Dennis ♦

Komentáře

  • Na něco jsem přišel! Při procházení zdroje Pyth ‚ s jsem zjistil, že tento kód j na 1 a 0, které se snaží převést 1 na základní 0. Proč ta segfaults, nemám nápad …
  • Viz zde . j druhou mocninu základny a volá se rekurzivně, dokud základna není alespoň tak velká jako číslo. Protože základna je 0 , nikdy se to nestane. S dostatečně vysokým limitem rekurze získáte segfault.
  • @Dennis IDEone
  • @SeeRhino The Pyth interpreter nastavuje limit rekurze na 100 000. Alespoň na TIO to ‚ stačí na segfault.

Odpověď

C # – 62

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

C # / nebezpečné, 23 bajtů

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

Z nějakého důvodu nerozumím, *(int*)0=0 jen hodí NullReferenceException, zatímco tato verze poskytuje správné narušení přístupu.

Komentáře

  • int i=*(int*)0; vrací mi NullReferenceException.
  • Můžete zkusit získat přístup k negativnímu místu, například *(int*)-1=0 a získat narušení přístupu.
  • Zvláštní výjimkou je právě to, co clr zabalí to do a je bezvýznamný. Samotný operační systém ve všech těchto případech ve skutečnosti způsobí chybu seg.
  • Důvod, proč *(int*)0=0 vyvolá výjimku, je pravděpodobně způsoben optimalizací. Konkrétně, aby se zabránilo nákladům na kontrolu null, může optimalizátor odstranit nulové kontroly, ale když dojde k segfault, může to znovu vytvořit jako správný NullReferenceException.

Odpověď

19 znaků v C

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

Poškodí hodnotu návratové adresy hlavní funkce, takže po návratu main získá SIGSEGV.

Komentáře

  • Závisí to na rozvržení rámce zásobníku, takže v některé architektuře možná nemůže selhat.
  • Proč ne jednoduše main;, nebo main(){*""=0;}?
  • @Sapphire_Brick main; je již uveden v jiné odpovědi.
  • @saeedn Proč to tedy vůbec zveřejňovat? Tento není ‚ ani druhý nejkratší!
  • @Sapphire_Brick V době, kdy jsem zveřejňoval svůj, main; nebyl ‚ t zveřejněn a já jsem ‚ nevěděl, že to funguje. Poukázal jsem jen na to, že je to již dáno a nemá smysl měnit svou odpověď. Kromě toho zde lidé ‚ nezveřejňují příspěvky jen pro nejkratší dobu, někdy je zajímavý i jiný způsob řešení problému.

Odpověď

Cython, 14

Toto se často hodí pro účely ladění.

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

Odpověď

J (6)

memf 1 

memf znamená volnou paměť, 1 je interpretován jako ukazatel.

Komentáře

  • Proč 1 spíše než 0? Je legální uvolnit nulový ukazatel v J?

Odpověď

Matlab – ano, je to možné!

V reakci na mou otázku přišel Amro s tímto vtipem:

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

Komentáře

  • Uveďte prosím verzi Matlabu – R2015B (a 2016B také) jen vyvolá chybu: Chyba při používání setfield (řádek 56) Alespoň jedna je vyžadován index.
  • @FlorianCastellane Nyní nemůžeme vyzkoušet všechny verze, ale bylo potvrzeno, že v některých verzích, nejnovější je 2014b a nejdříve 2012a, je uveden segfault.

Odpověď

C – 14 znaků

Nezapomeňte sestavit prázdný soubor s cc -nostartfiles c.c

Vysvětlení:

Co se pokazilo, je to, že jsme s _start zacházeli, jako by to byla funkce C, a pokusil se z toho vrátit. Ve skutečnosti to není vůbec funkce. Je to jen symbol v souboru objektu, který linker používá k vyhledání vstupního bodu programu. Když je vyvolán náš program, je vyvolán přímo. Pokud bychom se měli podívat, viděli bychom, že hodnota v horní části zásobníku byla číslo 1, což je určitě velmi neadresné. Ve skutečnosti je to hodnota argc našeho programu. Poté přichází prvky pole argv, včetně zakončovacího prvku NULL, následovaného prvky envp. A to je vše. V zásobníku není žádná zpáteční adresa.

Komentáře

  • I ‚ jsem si jistý, že musíte bodovat s dalšími args
  • Pro speciální příznak musíte přidat 14 bajtů.
  • @ErikGolfer エ リ ッ ク ゴ ル フ ァ ー -nostartfiles je ve skutečnosti 13 bajtů dlouhý 🙂
  • @CharlesPaulet Myslím, že musíte počítat také prostor.

Odpovědět

Sestava Unix PDP-11, 18 bajtů binární, 7 bajtů zdroj

(to se u mě stává tématem, možná proto, že je to jediný jazyk, o kterém vím, že ne – jeden jiný zde dělá.)

inc(r0) 

Zvyšuje jeden bajt adresovaný počáteční hodnotou r0 [což je podle simh debuggeru 05162] od spuštění programu.

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

A jako vždy lze cizí bajty na konci odstranit pomocí stripu.

Vytvořil jsem několik pokusy o zkrácení zdroje, ale vždy skončily ge buď syntaktická chyba, nebo SIGBUS.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *