Schreiben Sie den kürzesten Code, der einen Segmentierungsfehler (SIGSEGV) auslöst, in einer beliebigen Programmiersprache.
Schreiben Sie den kürzesten Code, der einen Segmentierungsfehler (SIGSEGV) auslöst, in einer beliebigen Programmiersprache.
Antworten:
main;
Es handelt sich um eine Variablendeklaration. Der int
Typ ist impliziert (Feature aus der Sprache B kopiert) und der 0
Standardwert. Bei der Ausführung wird versucht, eine Zahl auszuführen (Zahlen sind nicht ausführbar) und verursacht SIGSEGV
.
0
. static
Variablen beginnen , wie 0
, und main;
ist static
, wie ich es außerhalb Funktion erklärt. c-faq.com/decl/initval.html
main
ein int, der sich in .bss
befindet. In der Regel befinden sich Funktionen in .text
, wenn der Kernel das Elf-Programm lädt, für das er eine ausführbare Seite erstellt, .text
und nicht -executable für. Wenn Sie .bss
also main aufrufen, springen Sie zu einer nicht ausführbaren Seite, und die Ausführung von etwas auf einer solchen Seite ist eine Schutzverletzung.
main __attribute__((section(".text#")))=0xc3;
FTFY (zumindest scheint es, ohne Absturz auf meinem x86 zurückzukehren).
const main=195;
. So interessant es ist, dass es funktioniert, das Ziel dieser Code-Golf-Herausforderung war es, den Code fehlerfrei zu machen und nicht zu funktionieren :).
kill -11 $$
RET
Dieser Code ist fehlerhaft.
exec'()'*7**6
Windows meldet einen Fehlercode von c00000fd (Stack Overflow), von dem ich annehmen würde, dass es sich um einen Untertyp eines Segmentierungsfehlers handelt.
Dank Alex A. und Mego können Segmentierungsfehler auch auf Mac- und Linux-Systemen auftreten. Python ist die Sprache der Wahl, um Ihre Programme portabel zum Absturz zu bringen.
Segmentation fault: 11
auf Mac
Segmentation fault (core dumped)
unter Linux
\def~#1{\meaning}\write0{\expandafter~\string}\bye
Dies ist tatsächlich wahrscheinlich ein Fehler , aber es ist nicht in dem von Knuth geschriebenen Original-TeX vorhanden: Das Kompilieren des Codes mit tex filename.tex
anstelle von pdftex filename.tex
erzeugt keinen Segfault.
OBTW
Funktioniert nicht online, nur im C-Interpreter.
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Quelle: http://bugs.python.org/issue1215#msg143236
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Quelle: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup
Dies ist die Python-Version, auf der ich teste:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Im Allgemeinen ist der Python-Interpreter schwer zum Absturz zu bringen, aber das Obige ist selektiver Missbrauch ...
main(){raise(11);}
int func()
. dh eine Funktion int
, die zurückgibt und nicht spezifizierte Parameter verwendet. In diesem Fall raise
gibt eine Funktion int zurück, wobei ein int-Argument verwendet wird. Dies funktioniert also (auch wenn der Compiler sich beschwert).
/(?{??})/
In 5.14 wurde die Regex-Engine reentrant gemacht, so dass sie nicht auf diese Weise abgestürzt werden konnte. In 5.12 und früheren Versionen tritt jedoch ein Fehler auf, wenn Sie dies versuchen.
Dies scheint seltsam, aber auf 32 - Bit - Windows - Systemen erstellen und eine leere .com - Datei ausführen kann eine segfault verursachen, je nach ... etwas. DOS akzeptiert es einfach (der 8086 hat keine Speicherverwaltung, es sind keine bedeutenden Segmente zu bemängeln), und 64-Bit-Windows weigert sich, es auszuführen (x86-64 hat keinen v86-Modus, in dem eine .com-Datei ausgeführt werden kann).
<.
Ja, das ist implementierungsabhängig. SIGSEGV ist wahrscheinlich das Ergebnis eines guten Compilers.
<
sollte entweder keine Wirkung haben oder sich herumschlagen.
foreign import ccall main::IO()
Dies erzeugt einen Segfault, wenn es mit GHC kompiliert und ausgeführt wird. Es sind keine Erweiterungsflags erforderlich, da die Fremdfunktionsschnittstelle dem Haskell 2010-Standard entspricht.
C-Version ist:
*(int*)0=0;
Das gesamte Programm (nicht ganz ISO-konform, nehmen wir an, es ist K & R C) besteht aus 19 Zeichen:
main(){*(int*)0=0;}
Assembler-Variante:
orl $0,0
Das gesamte Programm ist 24 Zeichen lang (nur zur Bewertung, da es sich nicht um einen Assembler handelt):
main(){asm("orl $0,0");}
EDIT :
Ein paar C-Varianten. Die erste Methode verwendet die Nullinitialisierung der globalen Zeigervariablen:
*p;main(){*p=0;}
Die zweite Methode verwendet die unendliche Rekursion:
main(){main();}
Die letzte Variante ist die kürzeste - 7 (15) Zeichen.
EDIT 2 :
Erfand eine weitere Variante, die kürzer ist als eine der oben genannten - 6 (14) Zeichen. Es wird davon ausgegangen, dass Literalzeichenfolgen in einem schreibgeschützten Segment abgelegt werden.
main(){*""=0;}
EDIT 3 :
Und mein letzter Versuch - 1 Charakter lang:
P
Kompiliere es einfach so:
cc -o segv -DP="main(){main();}" segv.c
main
handelt es sich um eine mit Null initialisierte globale int-Variable. Was wir also erhalten, ist das Ergebnis des Versuchs, einige Null-Bytes auszuführen. In x86 wäre es so etwas wie add %al,(%rax)
ein perfekt gültiger Befehl, der versucht, den Speicher unter der in gespeicherten Adresse zu erreichen %rax
. Die Chancen, dort eine gute Adresse zu haben, sind gering.
[dx0]dx
verursacht einen Stapelüberlauf
[dx0]
speichert dx0
auf dem Stapel, d
dupliziert dann das oberste Stapelelement, x
fügt dann das oberste Stapelelement ein ( dx0
) und führt es aus. Das oberste Stack-Element wird dupliziert und ausgeführt. Es 0
muss vorhanden sein, um zu verhindern, dass dies ein Tail-Aufruf ist, damit sich alle Elemente aufbauen.
Eine etwas betrügerische Lösung besteht darin, einen Char von Joey Adams Bash-Trick zu entfernen :
kill 11,$$
Es liegt jedoch auf unpack p
der Hand , einen echten Segfault in Perl zu erhalten :
unpack p,1x8
Technisch wird dies nicht garantiert segfault, da die Adresse 0x31313131 (oder 0x3131313131313131 auf 64-Bit - Systemen) nur auf gültigen Adressraum zufällig hindeuten könnte. Aber die Chancen stehen dagegen. Wenn Perl jemals auf Plattformen portiert wird, auf denen Zeiger länger als 64 Bit sind, muss die x8
Anzahl erhöht werden.
1x8
Ding?
"11111111".
Obj.magic 0 0
Hierbei wird die Funktion verwendet Obj.magic
, die zwei beliebige Typen unsicher zwingt. In diesem Fall wird 0 (gespeichert als unmittelbarer Wert 1 aufgrund des vom GC verwendeten Tag-Bits) zu einem Funktionstyp (gespeichert als Zeiger) gezwungen. Daher wird versucht, die Adresse 1 zu dereferenzieren, und dies führt natürlich zu einem Fehler.
it coerces 0 (stored as the immediate value 1)
- Warum wird 0 als 1 gespeichert?
Obj.magic()0
ist ein char kürzer :)
Golf gespielt
. $0
Fügen Sie das Skript rekursiv in sich selbst ein.
Erklärt
Die rekursive Operation "source" (.) Führt schließlich zu einem Stapelüberlauf, und da Bash nicht in libsigsegv integriert ist , führt dies zu einem SIGSEGV.
Beachten Sie, dass dies kein Fehler ist, sondern ein erwartetes Verhalten, wie hier beschrieben .
Prüfung
./bang
Segmentation fault (core dumped)
⌠[]+⌡9!*.
Wenn dies nicht zum Absturz führt, erhöhen Sie die Zahl (mehrstellige Zahlen sind in Tatsächlich mit einem vorangestellten Doppelpunkt angegeben).
Beeinträchtigt den Interpreter, indem ein Fehler in Python ausgenutzt wird , der tief verschachtelte itertools.chain
Objekte umfasst, mit denen der +
Operator tatsächlich implementiert wird .
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
unsafe{int i=*(int*)0;}
Muss mit / unsafe kompiliert werden, damit dies funktioniert. Aus irgendeinem Grund verstehe ich nicht, *(int*)0=0
wirft nur eine NullReferenceException, während diese Version die richtige Zugriffsverletzung gibt.
int i=*(int*)0;
gibt eine NullReferenceException für mich zurück.
*(int*)-1=0
und erhalten eine Zugriffsverletzung.
*(int*)0=0
eine Ausnahme ausgelöst wird, liegt wahrscheinlich an der Optimierung. Um die Überprüfungskosten zu vermeiden null
, entfernt das Optimierungsprogramm möglicherweise Nullprüfungen. Wenn jedoch ein Segfault auftritt, wird er möglicherweise erneut als ordnungsgemäß ausgewiesen NullReferenceException
.
$ pil
: ('0)
Segmentation fault
Dies ist beabsichtigtes Verhalten. Wie auf ihrer Website beschrieben:
Wenn einige Programmiersprachen behaupten, das "Schweizer Taschenmesser der Programmierung" zu sein, kann PicoLisp als "Skalpell der Programmierung" bezeichnet werden: Scharf, genau, klein und leicht, aber auch gefährlich in der Hand von Unerfahrenen.
real,pointer::p(:)=>null()
p(1)=0.
end
Zusammenstellung:
gfortran segv.f90 -o segv
Ausführung:
./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)
Materialien:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
main(a){*(&a-1)=1;}
Es beschädigt den Rücksprungadressenwert der Hauptfunktion, sodass es bei der Rückgabe von ein SIGSEGV erhält main
.
(Dies wird ein Thema für mich, vielleicht weil es die einzige Sprache ist, die ich kenne, die hier sonst niemand kennt.)
inc(r0)
Inkrementiert das einzelne Byte, das durch den Anfangswert von r0 adressiert wird [der laut simh-Debugger zufällig 05162 ist], ab Programmstart.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
Und wie immer können die überflüssigen Bytes am Ende mit strip entfernt werden.
Ich habe ein paar Versuche unternommen, die Quelle zu verkürzen, bekam aber immer entweder einen Syntaxfehler oder SIGBUS.
In einer Antwort auf eine Frage von mir kam Amro mit dieser Eigenart:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
clear()
Löscht absolut alles, nicht nur das aktuelle Zielfernrohr, das offensichtlich viele Fehler verursacht, die dazu führen, dass JS in die Luft sprengt und Fehler verursacht
j1Z
Dies wäre der Teil, in dem ich erkläre, wie ich auf diese Antwort gekommen bin, außer ich habe zu Recht keine Ahnung . Wenn mir jemand das erklären könnte, wäre ich dankbar.
Hier ist es in einem Online-Dolmetscher.
Erläuterung
j
quadriert die Basis und ruft sich selbst rekursiv auf, bis die Basis mindestens so groß ist wie die Zahl. Da die Basis 0 ist, passiert das nie. Mit einem ausreichend hohen Rekursionslimit erhalten Sie einen Segfault.
j
auf 1
und 0
, die versucht , konvertieren 1
in der Basis 0
. Warum das so ist, weiß ich nicht ...