Le code le plus court qui soulève un SIGSEGV


Réponses:


113

C, 5 personnages

main;

C'est une déclaration de variable - le inttype est implicite (fonctionnalité copiée à partir du langage B) et sa 0valeur par défaut. Lorsqu'elle est exécutée, cette option tente d'exécuter un nombre (les nombres ne sont pas exécutables) et les causes SIGSEGV.

Essayez-le en ligne!


5
@ Macmade: En fait, ça l'est 0. staticles variables commencent comme 0, et main;sont static, comme je l'ai déclaré en dehors de la fonction. c-faq.com/decl/initval.html
Konrad Borowski

16
La dernière fois que j'ai joué avec ce truc, j'ai découvert qu'il y avait une raison différente pour le segfault. Tout d’abord en appelant main principal, vous accédez à l’emplacement principal et non à la valeur. Un autre problème est mainun int, il est situé dans .bss, les fonctions sont généralement situées dans .text. Lorsque le noyau charge le programme elf, il crée une page exécutable pour .textet non. -executable for .bss, donc en appelant main, vous passez à une page non-exécutable, et l'exécution de quelque chose sur une telle page est une faute de protection.
Mniip

23
Oui, les segfaults en C sont quasiment les défauts: P
Paul Draper

1
main __attribute__((section(".text#")))=0xc3;FTFY (du moins ça a l'air de revenir sans planter sur mon x86).
jozxyqk

2
@jozxyqk ou moins, const main=195;. Ce qui est intéressant, c’est que ça marche, le but de ce défi de jouer au code était de faire en sorte que le code segfault, et non pas fonctionne :)
Konrad Borowski

74

Bash, 11      

kill -11 $$

44
Signal 11 en 11 caractères. Semble légitime.
nyuszika7h

12
@ nyuszika7h J'allais upvoter votre commentaire, mais vous avez 11 upvotes pour le moment, alors je vais en rester là. : P
HyperNeutrino

3
@ AlexL. d'autres personnes semblent avoir gâché que :(
theonlygusti

2
@theonlygusti Ouais ... C'est dommage. :( Oh bien, alors je peux passer au vote maintenant.
HyperNeutrino

2
Jusqu'à 42 votes positifs, aucun touché!
seadoggie01

39

Assembly (Linux, x86 à 64), 1 octet

RET

Ce code segfaults.


7
En tant que fichier MSDOS .com, il s'exécute et se termine sans erreur.
JB

10
Mon objectif étant: le simple fait de spécifier «assembly» ne suffit pas pour le rendre segfault.
JB

53
@JB: Sous MS-DOS, aucun programme ne générera jamais d' erreur de segmentation. En effet, MS-DOS s'exécute en mode réel où la protection de la mémoire est inexistante.
celtschk

1
@celtschk IIRC NTVDM supprimera les adresses inexistantes et celles non attribuées à MS-DOS.
ζ--

2
@celtschk: Vous pouvez quand même le faire segfault comme ceci: mov bx, 1000h; shr ebx, 4; mov eax, [ebx] -> Le processeur soulève le SEGV sous-jacent (autant que je sache, personne ne le gère cependant).
Josué

26

Python 2, 13

exec'()'*7**6

Windows signale un code d'erreur c00000fd (débordement de pile) qui, je suppose, est un sous-type d'erreur de segmentation.

Merci à Alex A. et Mego, il a été confirmé qu’il pouvait également causer des erreurs de segmentation sur les systèmes Mac et Linux. Python est le langage de choix pour le crash portable de vos programmes.


7
Segmentation fault: 11sur Mac
Alex A.

7
Segmentation fault (core dumped)sur Linux
Mego

Est-ce que ça raccroche en premier?
Mega Man

1
@ MegaMan As-tu pris beaucoup de temps pour terminer? Non, 7 ** 6 ne représente qu'environ 100K, il n'y a donc aucun délai perceptible.
Feersum

Pourquoi ça marche? Il ne semble pas que sur Python 3.6.8 sur Mac OS.
Max Gasner

22

pdfTeX (51)

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

C’est en fait probablement un bogue , mais il n’est pas présent dans le TeX original, écrit par Knuth: compiler le code avec tex filename.texau lieu de pdftex filename.texne produit pas de segfault.



17

Python, 33 caractères

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

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

Python, 60 caractères

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

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

Voici la version Python sur laquelle je teste:

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

En général, l'interpréteur Python est difficile à planter, mais ce qui précède est abusif sélectif ...


16

Forth - 3 personnages

0 @

( @est un chercher)


1
Le plus court à ce jour qui fonctionnera sur les systèmes modernes.
Demi

2
Quel Forth? Gforth dit simplement "Adresse mémoire invalide"
Cat

15

C, 18

main(){raise(11);}

Devez-vous ajouter #include <signal.h> dans la liste de code?
Florian Castellane

5
@FlorianCastellane: en C90 et inférieur, pour tout appel de fonction effectué sans déclaration visible, le compilateur le déclare implicitement comme int func(). c'est à dire une fonction retournant int, prenant des paramètres non spécifiés. Dans ce cas, il raises’agit d’une fonction renvoyant int, prenant un argument int, donc cela fonctionne (même si le compilateur se plaint).
Hasturkun

14

Perl (<5.14), 9 caractères

/(?{??})/

En 5.14, le moteur des expressions rationnelles a été rendu réentrant de sorte qu'il ne puisse pas être planté de cette façon, mais 5.12 et les versions antérieures segfont par défaut si vous essayez ceci.


Je peux reproduire cela sur Perl 5.14 (Debian) et 5.18 (Arch Linux). sprunge.us/RKHT
nyuszika7h

Reproduit avec Perl v5.20.2 (windows)
mehi

14

W32 .com exécutable - 0 octet

Cela semblera étrange, mais sur les systèmes Windows 32 bits, la création et l’exécution d’un fichier .com vide peut entraîner une erreur de segmentation, selon ... quelque chose. DOS l'accepte simplement (le 8086 n'ayant pas de gestion de mémoire, il n'y a pas de segments significatifs à blâmer) et Windows 64 bits refuse de l'exécuter (x86-64 n'ayant pas de mode v86 pour exécuter un fichier .com).


13

brainfuck (2)

<.

Oui, cela dépend de la mise en œuvre. SIGSEGV est le résultat probable d'un bon compilateur.


4
Comment est un compilateur qui segfaults sur ce "bon"? Cela <devrait soit n'avoir aucun effet ou envelopper.
nyuszika7h

12
Il est préférable de produire immédiatement une violation d’erreur d'exécution au niveau des limites, car cela permet au programmeur de rechercher et de corriger le bogue le plus rapidement possible. Laisser le programme bogué fonctionner pendant un moment et corrompre la mémoire au hasard avant de tomber en panne rend le problème plus difficile à diagnostiquer. Comme vous le suggérez, il est pire que d'empêcher l'accident. le programmeur peut faire en sorte que le programme «fonctionne», puis être humilié publiquement lorsqu'il se bloque sur des compilateurs et des interprètes standard.
Daniel Cristofani

1
Inversement, la détection des violations de limites avant l'exécution n'est généralement pas possible, ni particulièrement utile dans les cas où cela est possible. Produire une erreur d'exécution plus descriptive serait acceptable, mais il est préférable que le système d'exploitation la détecte comme une erreur de segmentation car elle n'a pas de coût de rapidité. (Au cas où ce ne soit pas clair, le compilateur lui-même ne commet pas d'erreur de segmentation - il produit des exécutables qui segfèrent dès qu'ils essaient d'accéder à la mémoire en dehors des limites.)
Daniel Cristofani

4
Pouvez-vous fournir une implémentation qui génère ce problème et a été créée avant la publication de ce défi? Sinon, cette réponse est invalide.
Mego

1
Les contrôles des limites sont spécifiques à l'implémentation, donc je suis sûr qu'il y en a qui pourraient s'y tromper. Est-ce que tout SIGSEGV? J'en doute. Il existe cependant un grand nombre de programmes qui dépendent du wrapping du tableau situé à gauche. Il peut être assez pratique d’avoir un espace de stockage pouvant être développé des deux côtés.
captncraig

12

Haskell, 31 ans

foreign import ccall main::IO()

Cela produit une erreur de segmentation une fois compilé avec GHC et exécuté. Aucun indicateur d'extension n'est nécessaire, l'interface de fonction étrangère étant au standard Haskell 2010.


10

C - 11 (19) 7 (15) 6 (14) 1 caractères, assembleur AT & T x86 - 8 (24) caractères

La version C est:

*(int*)0=0;

L'ensemble du programme (pas tout à fait conforme à ISO, supposons qu'il s'agisse de K & R C) comporte 19 caractères:

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

Variante d'assembleur:

orl $0,0

Le programme entier a une longueur de 24 caractères (juste pour l'évaluation, car ce n'est pas réellement un assembleur):

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

EDIT :

Un couple de variantes C Le premier utilise l'initialisation zéro de la variable de pointeur global:

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

Le second utilise une récursion infinie:

main(){main();}

La dernière variante est la plus courte - 7 (15) caractères.

EDIT 2 :

Inventé une autre variante qui est plus courte que l'une des précédentes - 6 (14) caractères. Il suppose que les chaînes littérales sont placées dans un segment en lecture seule.

main(){*""=0;}

EDIT 3 :

Et mon dernier essai - 1 caractère long:

P

Il suffit de le compiler comme ça:

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

3
en C n'est pas principal; seulement 5 personnages
Arya

1
: Linker ne vérifie pas si main est fonctionnel ou pas. Il suffit de le passer au chargeur et de le renvoyer sigsegv
Arya

1
@FUZxxl Dans ce cas, il mains'agit d'une variable int globale initialisée à zéro. Nous obtenons donc le résultat d'une tentative d'exécution de zéro octet. En x86, ce serait quelque chose comme add %al,(%rax)une instruction parfaitement valide qui tente d’atteindre la mémoire à une adresse stockée dans %rax. Les chances d'avoir une bonne adresse sont minimes.
Alexander Bakulin

6
Bien sûr, la dernière entrée peut être utilisée pour tout, il vous suffit de fournir les bons arguments du compilateur. Ce qui devrait en faire le gagnant automatique de tout concours de golf de code. :-)
celtschk

5
Généralement, les indicateurs du compilateur autres que ceux qui choisissent la version de langue à utiliser sont pris en compte dans le total.
Jerry Jeremiah

9

dc - 7 caractères

[dx0]dx

provoque un débordement de pile


Est-ce des œuvres, mais pouvez-vous élaborer? Pourquoi se comporte-t-il de cette façon?
Stéphane Gourichon

2
[dx0]stocke dx0sur la pile, puis dduplique l'élément de pile supérieur, puis xaffiche l'élément de pile supérieur ( dx0) et l'exécute. Ce qui duplique l’élément supérieur de la pile et commence à l’exécuter ... c’est 0nécessaire pour éviter que cela ne soit un appel final, de sorte qu’ils se développent tous.
Ben Millwood,

8

Perl, 10/12 caractères

Une solution légèrement tricheuse est de supprimer un personnage du tour basque de Joey Adams :

kill 11,$$

Cependant, obtenir une réelle erreur de segmentation dans Perl unpack pest la solution évidente:

unpack p,1x8

Techniquement, cette erreur de segmentation n'est pas garantie , car l'adresse 0x31313131 (ou 0x3131313131313131 sur les systèmes 64 bits) peut simplement pointer sur un espace adresse valide par hasard. Mais les chances sont contre elle. De plus, si perl est porté sur des plates-formes où les pointeurs ont une longueur supérieure à 64 bits, x8il faudra l'augmenter.


1
Quelle est cette 1x8chose?
Hannes Karppila

@HannesKarppila C'est un court chemin pour écrire"11111111".
Ilmari Karonen

8

Python 33

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

Envoi du signal 11 (SIGSEGV) en python.


2
Aussi 33 caractères: from os import*etkill(getpid(),11)
Timtech

8

OCaml, 13 octets

Obj.magic 0 0

Ceci utilise la fonction Obj.magic, qui contraint deux types quelconques. Dans ce cas, il force 0 (stocké en tant que valeur immédiate 1 en raison du bit de balise utilisé par le GC) en un type de fonction (stocké sous la forme d'un pointeur). Ainsi, il essaie de déréférencer l'adresse 1, et ce sera bien sûr une erreur de segmentation.


1
it coerces 0 (stored as the immediate value 1)- pourquoi 0 est-il stocké comme 1?
Skyler

1
@Skyler see edit
Demi

1
Obj.magic()0est un caractère plus court :)
Ben Millwood

8

Bash, 4 octets

Golfé

. $0

Inclure récursivement le script en lui-même.

A expliqué

Une opération "source" récursive (.) Provoque éventuellement un débordement de pile et, comme Bash ne s'intègre pas à libsigsegv , il en résulte un SIGSEGV.

Notez qu'il ne s'agit pas d'un bogue, mais d'un comportement attendu, comme discuté ici .

Tester

./bang 
Segmentation fault (core dumped)

Essayez-le en ligne!


8

En fait , 17 16 11 10 9 octets

⌠[]+⌡9!*.

Essayez-le en ligne!

Si ce qui précède ne plante pas, essayez d’augmenter le nombre (des nombres à plusieurs chiffres sont spécifiés dans En fait avec un signe deux-points)

Bloque l'interprète en exploitant un bogue dans Python impliquant des itertools.chainobjets profondément imbriqués , qui utilise en réalité pour implémenter l' +opérateur.


7

C # - 62

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

Édition: 23

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

Compiler avec / unsafe pour que celui-ci fonctionne. Pour une raison quelconque, je ne comprends pas, *(int*)0=0lève simplement une exception NullReferenceException, alors que cette version donne la violation d'accès appropriée.


Le int i=*(int*)0;renvoie une exception NullReferenceException pour moi.
Peter Olson

Vous pouvez essayer d'accéder à un emplacement négatif, comme *(int*)-1=0une violation d'accès.
Peter Olson

L'exception particulière est juste ce que l'enveloppe l'enveloppe, et est insignifiant. Le système d'exploitation lui-même donne réellement la faute distincte dans tous ces cas.
captncraig

La raison pour laquelle *(int*)0=0une exception est générée est probablement due à l'optimisation. En particulier, pour éviter les coûts de vérification null, l'optimiseur peut supprimer les vérifications nulles, mais lorsqu'un défaut de segmentation se produit, il peut le redéfinir correctement NullReferenceException.
Konrad Borowski

7

PicoLisp - 4 caractères

$ pil
: ('0)
Segmentation fault

Ceci est le comportement prévu. Comme décrit sur leur site web:

Si certains langages de programmation prétendent être le "couteau suisse de la programmation", alors PicoLisp pourrait très bien s'appeler le "Scalpel of Programming": précis, précis, petit et léger, mais aussi dangereux pour les inexpérimentés.


7

F90 - 39 octets

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

Compilation:

gfortran segv.f90 -o segv 

Exécution:

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

Matériaux:

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

1
Nice premier post.
Rɪᴋᴇʀ

6

19 caractères en C

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

Il corrompt la valeur d'adresse de retour de la fonction principale et obtient donc un SIGSEGV au retour de main.


Cela dépend de la disposition du cadre de pile, de sorte que dans certaines architectures, cela ne peut éventuellement pas échouer.
Alexander Bakulin

6

J (6)

memf 1

memfsignifie mémoire libre, 1est interprété comme un pointeur.


5

Cython, 14

Cela est souvent utile pour le débogage.

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

5

Assemblage Unix PDP-11, binaire 18 octets, source 7 octets

(Cela devient un thème pour moi, peut-être parce que c'est la seule langue que je sais en quelque sorte que personne d'autre ne connaît ici.)

inc(r0)

Incrémente le seul octet adressé par la valeur initiale de r0 [qui se trouve être 05162 en fonction du débogueur simh] dès le début du programme.

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

Et, comme toujours, les octets superflus à la fin peuvent être supprimés avec strip.

J'ai fait quelques tentatives pour obtenir la source plus courte, mais j'ai toujours eu une erreur de syntaxe ou SIGBUS.


5

Matlab - Oui c'est possible!

En réponse à une de mes questions , Amro a proposé cette bizarrerie:

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

Veuillez indiquer à la version Matlab - R2015B (et 2016B également) qu'une erreur est générée: Erreur lors de l'utilisation de setfield (ligne 56) Au moins un index est requis.
Florian Castellane

@FlorianCastellane Impossible d'essayer toutes les versions pour le moment, mais il a été confirmé qu'un segfault était créé dans plusieurs versions, la dernière en date étant 2014b et la plus ancienne en 2012a.
Dennis Jaheruddin

5

JavaScript shell, 7 octets

clear()

Efface absolument tout, pas seulement la portée actuelle qui provoque évidemment beaucoup de bouchons qui font exploser JS et segfault


Selon MDN (document.clear), cela ne devrait fonctionner que dans des versions vraiment anciennes de Mozilla, et même dans ce cas, qu'est-ce qui segfaults dans votre expérience?
Tomsmeding

@ tomsmeding c'est window.clear, FF ne le révèle pas directement, c'est un spidermonkey intégré
Downgoat

5

Pyth, 3 personnages

j1Z

Ce serait la partie où j'explique comment j'ai trouvé cette réponse, sauf que je n'ai légitimement aucune idée . Si quelqu'un pouvait expliquer cela pour moi, je vous en serais reconnaissant.

La voici dans un interprète en ligne.

Explication

jmet la base en carré et s’appelle récursivement jusqu’à ce que la base soit au moins aussi grande que le nombre. Puisque la base est 0 , cela ne se produit jamais. Avec une limite de récursion suffisamment élevée, vous obtenez une erreur de segmentation.

- Dennis ♦


J'ai compris quelque chose! En parcourant le code source de Pyth, j'ai constaté que ce code fonctionne jsur 1et 0, qui tente de convertir 1en base 0. Pourquoi ces segfaults, je n'en ai aucune idée ...
NoOneIsHere

1
Voir ici . jmet la base en carré et s’appelle récursivement jusqu’à ce que la base soit au moins aussi grande que le nombre. Puisque la base est 0 , cela ne se produit jamais. Avec une limite de récursion suffisamment élevée, vous obtenez une erreur de segmentation.
Dennis

@Dennis IDEone
NoOneIsHere

@SeeRhino L'interpréteur Pyth définit la limite de récursivité à 100 000. Au moins sur TIO, cela suffit pour une erreur de segmentation.
Dennis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.