Scrivi il codice più breve che genera un errore di segmentazione (SIGSEGV) in qualsiasi linguaggio di programmazione.
Scrivi il codice più breve che genera un errore di segmentazione (SIGSEGV) in qualsiasi linguaggio di programmazione.
Risposte:
main;
È una dichiarazione variabile - il inttipo è implicito (funzione copiata dal linguaggio B) ed 0è un valore predefinito. Quando eseguito, tenta di eseguire un numero (i numeri non sono eseguibili) e causa SIGSEGV.
0. staticle variabili iniziano come 0, ed main;è static, come l'ho dichiarato al di fuori della funzione. c-faq.com/decl/initval.html
mainun int, si trova in .bss, di solito le funzioni si trovano in .text, quando il kernel carica il programma elf crea una pagina eseguibile per .texte non eseguibile per .bss, quindi chiamando main, si passa a una pagina non eseguibile e l'esecuzione di qualcosa su tale pagina è un errore di protezione.
main __attribute__((section(".text#")))=0xc3;FTFY (almeno sembra tornare senza crash sul mio x86).
const main=195;. Per quanto interessante sia il suo funzionamento, l'obiettivo di questa sfida di golf del codice era rendere il codice segfault, non funzionare :).
kill -11 $$
RET
Questo codice segfault.
exec'()'*7**6
Windows riporta un codice di errore di c00000fd (StackTranslate.it) che suppongo sia un sottotipo di errore di segmentazione.
Grazie ad Alex A. e Mego, è confermato che causa errori di segmentazione anche su sistemi Mac e Linux. Python è la lingua preferita per bloccare in modo portabile i tuoi programmi.
Segmentation fault: 11su Mac
Segmentation fault (core dumped)su Linux
\def~#1{\meaning}\write0{\expandafter~\string}\bye
Questo in realtà è probabilmente un bug , ma non è presente nel TeX originale, scritto da Knuth: compilare il codice con tex filename.texinvece di pdftex filename.texnon produce un segfault.
OBTW
Non funziona online, solo nell'interprete C.
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Fonte: http://bugs.python.org/issue1215#msg143236
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Fonte: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup
Questa è la versione di Python su cui sto testando:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
In generale, l'interprete Python è difficile da bloccare, ma quanto sopra è l'abusività selettiva ...
main(){raise(11);}
int func(). cioè una funzione che ritorna int, prendendo parametri non specificati. In questo caso raiseè una funzione che restituisce int, prendendo un argomento int, quindi questo funziona (anche se il compilatore si lamenta).
/(?{??})/
In 5.14 il motore regex è stato reso rientrante in modo da non poter essere arrestato in questo modo, ma 5.12 e versioni precedenti verranno segfault se provi questo.
Sembrerà strano, ma su sistemi Windows a 32 bit, la creazione e l'esecuzione di un file .com vuoto possono causare un segfault, a seconda di ... qualcosa. DOS lo accetta (l'8086 non ha gestione della memoria, non ci sono segmenti significativi da criticare) e Windows a 64 bit rifiuta di eseguirlo (x86-64 non ha la modalità v86 per eseguire un file .com).
<.
Sì, questo dipende dall'implementazione. SIGSEGV è il probabile risultato di un buon compilatore.
<dovrebbe avere alcun effetto o concludersi.
foreign import ccall main::IO()
Questo produce un segfault quando compilato con GHC ed eseguito. Non sono necessari flag di estensione, poiché l'interfaccia di funzione esterna è nello standard Haskell 2010.
La versione C è:
*(int*)0=0;
L'intero programma (non abbastanza conforme all'ISO, supponiamo che sia K&R C) è lungo 19 caratteri:
main(){*(int*)0=0;}
Variante assemblatore:
orl $0,0
L'intero programma è lungo 24 caratteri (solo per valutazione, dal momento che in realtà non è assemblatore):
main(){asm("orl $0,0");}
MODIFICA :
Un paio di varianti C. Il primo utilizza l'inizializzazione zero della variabile puntatore globale:
*p;main(){*p=0;}
Il secondo utilizza una ricorsione infinita:
main(){main();}
L'ultima variante è la più breve - 7 (15) caratteri.
EDIT 2 :
Ha inventato una variante in più che è più corta di qualsiasi di sopra - 6 (14) caratteri. Presuppone che le stringhe letterali vengano inserite in un segmento di sola lettura.
main(){*""=0;}
EDIT 3 :
E il mio ultimo tentativo - 1 carattere lungo:
P
Compilalo così:
cc -o segv -DP="main(){main();}" segv.c
mainè una variabile int globale inizializzata con zero, quindi quello che otteniamo è il risultato del tentativo di eseguire alcuni byte zero. In x86 sarebbe qualcosa del genere add %al,(%rax)che è un'istruzione perfettamente valida che cerca di raggiungere la memoria all'indirizzo memorizzato %rax. Le probabilità di avere un buon indirizzo sono minime.
[dx0]dx
provoca un overflow dello stack
[dx0]memorizza dx0sullo stack, quindi dduplica l'elemento stack superiore, quindi xfa apparire l'elemento stack superiore ( dx0) ed esegue. Il che duplica l'elemento superiore dello stack e inizia a eseguirlo ... 0deve essere lì per evitare che si tratti di una chiamata in coda, quindi si accumulano tutti.
Una soluzione leggermente imbarazzante è quella di radere un personaggio dal trucco bash di Joey Adams :
kill 11,$$
Tuttavia, per ottenere un vero segfault in Perl, unpack pè la soluzione ovvia:
unpack p,1x8
Tecnicamente, questo non è garantito per segfault, poiché l'indirizzo 0x31313131 (o 0x313131313131313131 su sistemi a 64 bit) potrebbe indicare uno spazio di indirizzi valido per caso. Ma le probabilità sono contro di esso. Inoltre, se il perl viene mai portato su piattaforme in cui i puntatori sono più lunghi di 64 bit, x8sarà necessario aumentare.
1x8cosa?
"11111111".
Obj.magic 0 0
Questo utilizza la funzione Obj.magic, che costringe in modo non sicuro due tipi qualsiasi. In questo caso, costringe 0 (memorizzato come valore immediato 1, a causa del bit di tag utilizzato dal GC) a un tipo di funzione (memorizzato come puntatore). Quindi, cerca di dereferenziare l'indirizzo 1, e questo ovviamente segfault.
it coerces 0 (stored as the immediate value 1)- perché 0 è memorizzato come 1?
Obj.magic()0è un carattere più corto :)
golfed
. $0
Includere ricorsivamente lo script in se stesso.
spiegato
L'operazione "source" (.) Ricorsiva provoca eventualmente uno overflow dello stack e poiché Bash non si integra con libsigsegv , ciò si traduce in un SIGSEGV.
Si noti che questo non è un bug, ma un comportamento previsto, come discusso qui .
Test
./bang
Segmentation fault (core dumped)
⌠[]+⌡9!*.
Se quanto sopra non va in crash, prova ad aumentare il numero (i numeri a più cifre sono specificati in In realtà con due punti iniziali)
Arresta in modo anomalo l'interprete sfruttando un bug in Python che coinvolge itertools.chainoggetti profondamente nidificati , che in realtà utilizza per implementare l' +operatore.
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
unsafe{int i=*(int*)0;}
Devi compilare con / non sicuro per far funzionare questo. Per qualche motivo non capisco, *(int*)0=0genera solo NullReferenceException, mentre questa versione fornisce la violazione di accesso corretta.
int i=*(int*)0;rendimenti di un NullReferenceException per me.
*(int*)-1=0e ottenere una violazione di accesso.
*(int*)0=0genera un'eccezione è probabilmente dovuto all'ottimizzazione. In particolare, per evitare il costo del controllo null, l'ottimizzatore può rimuovere i controlli nulli, ma quando si verifica un segfault può ripeterlo come corretto NullReferenceException.
$ pil
: ('0)
Segmentation fault
Questo è un comportamento previsto. Come descritto sul loro sito Web:
Se alcuni linguaggi di programmazione dichiarano di essere il "coltellino svizzero della programmazione", allora PicoLisp potrebbe essere definito il "bisturi della programmazione": nitido, preciso, piccolo e leggero, ma anche pericoloso nella mano di chi non ha esperienza.
real,pointer::p(:)=>null()
p(1)=0.
end
Compilazione:
gfortran segv.f90 -o segv
Esecuzione:
./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)
materiali:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
main(a){*(&a-1)=1;}
Corrompe il valore dell'indirizzo di ritorno della funzione principale, quindi ottiene un SIGSEGV al ritorno di main.
(questo sta diventando un tema per me, forse perché è l'unica lingua che conosco che nessun altro qui fa.)
inc(r0)
Incrementa il singolo byte indirizzato dal valore iniziale di r0 [che risulta essere 05162 secondo il debugger simh] all'inizio del programma.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
E, come sempre, i byte estranei alla fine possono essere rimossi con strip.
Ho fatto alcuni tentativi per accorciare l'origine, ma alla fine ho sempre avuto un errore di sintassi o SIGBUS.
In risposta a una mia domanda , Amro ha inventato questa stranezza:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
clear()
Cancella assolutamente tutto, non solo l'ambito attuale che ovviamente causa molti borks che provocano l'esplosione e la segfault di JS
j1Z
Questa sarebbe la parte in cui spiego come ho trovato questa risposta, a meno che non abbia legittimamente idea . Se qualcuno potesse spiegarmelo, sarei grato.
Eccolo in un interprete online.
Spiegazione
jquadra la base e si chiama ricorsivamente fino a quando la base è grande almeno quanto il numero. Poiché la base è 0 , ciò non accade mai. Con un limite di ricorsione sufficientemente elevato, si ottiene un segfault.
jsu 1e 0, che tenta di convertire 1in base 0. Perché questo segfault, non ne ho idea ...