Écrivez le code le plus court qui déclenche une Erreur de segmentation (SIGSEGV) dans nimporte quel langage de programmation.
Commentaires
- Wow. Peut-être la question la plus courte avec succès.
- @MatthewRoh Par intérêt, jai créé cette requête SEDE. Il semble quil y en ait quelques-uns avec +10 ou plus, mais cest le premier au-dessus de +40
Réponse
C, 5 caractères
main;
Cest une déclaration de variable – le type int
est implicite (fonction copiée depuis B language) et 0
est la valeur par défaut. Lorsquelle est exécutée, elle essaie dexécuter un nombre (les nombres ne sont pas exécutables) et provoque SIGSEGV
.
Commentaires
- @Macmade: En fait, cest
0
. Les variablesstatic
commencent par0
etmain;
eststatic
, comme je lai déclaré en dehors de la fonction. c-faq.com/decl/initval.html - la dernière fois que jai joué avec ce truc, jai compris quil y avait ‘ une raison différente de lerreur de segmentation. Tout dabord en appelant main vous sautez à lemplacement de main, pas la valeur, une autre chose est
main
est un int, il ‘ s situées dans.bss
, généralement les fonctions sont situées dans.text
, lorsque le noyau charge le programme elf, il crée une page exécutable pour.text
et non exécutable pour.bss
, donc en appelant main, vous passez à une page non exécutable, et lexécution de quelque chose sur une telle page est un défaut de protection. - Oui, les segfaults en C sont à peu près la valeur par défaut: P
-
main __attribute__((section(".text#")))=0xc3;
FTFY (au moins il semble revenir sans planter sur mon x86). - @jozxyqk Ou plus court,
const main=195;
. Comme il est intéressant de noter que cela ‘ fonctionne, le but de ce défi de golf de code était de rendre le code par défaut, pas de fonctionner :).
Réponse
Bash, 11
kill -11 $$
Commentaires
- Signal 11 en 11 caractères. Cela semble légitime.
- @ nyuszika7h Jallais voter pour votre commentaire, mais vous avez 11 votes pour le moment, donc je ‘ vais en rester là. : P
- @AlexL. dautres personnes semblent avoir gâché ça 🙁
- @theonlygusti Ouais … Cest ‘ que cest dommage. 🙁 Eh bien, alors je peux voter pour maintenant .
- Jusquà 42 votes positifs, aucune touche!
Réponse
Assembly (Linux , x86-64), 1 octet
RET
Ce code segfaults.
Commentaires
- En tant que fichier MSDOS .com, il sexécute et se termine sans erreur.
- Mon point étant: il suffit de spécifier «assembly» ‘ pour en faire une erreur de segmentation.
- @JB: Sous MS DOS, aucun programme ne produira jamais derreur de segmentation. Cela ‘ s parce que MS DOS fonctionne en mode réel où la protection de la mémoire est inexistante.
- @celtschk IIRC NTVDM va fonctionner sur des adresses inexistantes, et celles non allouées à MS-DOS.
- @celtschk: Vous pouvez quand même effectuer une segmentation comme suit: mov bx, 1000h; shr ebx, 4; mov eax, [ebx] – > Augmentation du CPU s le SEGV sous-jacent (AFAIK il ny a ‘ personne pour le gérer).
Réponse
Python 2, 13
exec"()"*7**6
Windows signale un code derreur de c00000fd (Stack Overflow) qui, je suppose, est un sous-type de erreur de segmentation.
Grâce à Alex A. et Mego, il est également confirmé quil provoque des erreurs de segmentation sur les systèmes Mac et Linux. Python est le langage de choix pour planter vos programmes de manière portable.
Commentaires
-
Segmentation fault: 11
sur Mac -
Segmentation fault (core dumped)
sous Linux - Cela se raccroche-t-il en premier?
- @MegaMan Comme dans prend beaucoup de temps pour terminer ? Non, 7 ** 6 ne représente quenviron 100 Ko, donc il ny a ‘ aucun retard perceptible.
- @MaxGasner Essayez de relire le langage de programmation 🙂
Réponse
pdfTeX ( 51)
\def~#1{\meaning}\write0{\expandafter~\string}\bye
Cest probablement un bogue , mais il nest pas présent dans le TeX original, écrit par Knuth: la compilation du code avec tex filename.tex
au lieu de pdftex filename.tex
ne produit pas de segfault.
Réponse
LOLCODE, 4 octets
OBTW
Ne fonctionne pas en ligne, uniquement dans linterpréteur C.
Commentaires
- LOL FANCY CODE M8 8/8 KTHXBYE
Réponse
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 n Je teste sur:
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, linterpréteur Python est difficile à planter, mais ce qui précède est un abus sélectif …
Réponse
Quatrième – 3 caractères
0 @
(@
est une extraction)
Commentaires
- Le plus court à ce jour qui fonctionnera sur les systèmes modernes.
- Et quoi? Gforth dit simplement » Adresse mémoire non valide »
Réponse
Exécutable W32 .com – 0 octet
Cela peut sembler étrange, mais sur les systèmes Windows 32 bits, créer et exécuter un fichier .com vide peut provoque un segfault, en fonction de … quelque chose. DOS laccepte simplement (le 8086 na pas de gestion de mémoire, il ny a pas de segments significatifs à mettre en défaut), et Windows 64 bits refuse de lexécuter (x86-64 nayant pas de mode v86 pour exécuter un fichier .com).
Réponse
C, 18
main(){raise(11);}
Commentaires
- devez-vous ajouter #include < signal.h > dans la liste des codes?
- @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()
. cest-à-dire une fonction renvoyantint
, prenant des paramètres non spécifiés. Dans ce cas,raise
est une fonction retournant int, prenant un argument int, donc cela fonctionne (même si le compilateur se plaint). - @Hasturkun
main(){main();}
Réponse
Perl (< 5.14), 9 caractères
/(?{??})/
En 5.14, le moteur regex a été rendu réentrant afin quil ne puisse pas être écrasé de cette façon, mais 5.12 et plus tôt segfault si vous essayez ceci.
Commentaires
- Je peux reproduire ceci sur Perl 5.14 (Debian) et 5.18 (Arch Linux). sprunge.us/RKHT
- Reproduit avec Perl v5.20.2 (windows)
- Et
/(?R)/
sur les anciennes versions de Perl?
Answer
brainfuck (2)
<.
Oui, cela dépend de limplémentation. SIGSEGV est le résultat probable dun bon compilateur.
Commentaires
- Comment un compilateur se sépare-t-il sur ce » bon « ? Cela
<
devrait soit n’avoir aucun effet, soit se terminer. - Il est préférable de produire immédiatement une erreur d’exécution en cas de violation des limites car cela permet au programmeur de trouver et de corriger le bogue comme aussi vite que possible. Laisser le programme bogué sexécuter pendant un certain temps et corrompre la mémoire au hasard avant de planter ne fait que rendre le problème plus difficile à diagnostiquer. Prévenir complètement le crash, comme vous le suggérez, est le pire; le programmeur peut faire fonctionner le programme » » puis être publiquement humilié quand il plante sur des compilateurs et interprètes standard.
- Inversement, attraper les violations de limites avant lexécution nest pas possible en général, ni particulièrement utile dans les cas où cela est possible. Produire une erreur dexécution plus descriptive serait acceptable, mais le fait que le système dexploitation lattrape comme une erreur de segmentation est génial parce que cela na ‘ aucun coût de vitesse. (Dans le cas où ‘ nest pas clair, le compilateur lui-même ne ‘ t segfault – il produit des exécutables qui segfault dès quils essaient) pour accéder à la mémoire hors limites.)
- Pouvez-vous fournir une implémentation qui produit ce comportement et qui a été créée avant la publication de ce défi? Sinon, cette réponse est invalide.
- Les vérifications de limites sont spécifiques à limplémentation, donc je ‘ suis sûr quil y en a qui pourraient faire des erreurs.Un SIGSEGV serait-il cependant? Jen doute. Il existe cependant un grand nombre de programmes qui dépendent de lencapsulation du tableau vers la gauche. Il peut être plutôt pratique davoir un stockage évolutif des deux côtés.
Réponse
Haskell, 31
foreign import ccall main::IO()
Cela produit un segfault lorsquil est compilé avec GHC et exécuté. Aucun indicateur dextension nest nécessaire, car linterface de fonction étrangère est dans la norme Haskell 2010.
Commentaires
- Awwww. Jallais publier
import Foreign;main=peek nullPtr::IO Int
, mais ce ‘ s 40.
Réponse
Bash, 4 octets
Golfed
. $0
Inclut récursivement le script en lui-même.
Expliqué
Récursif » source » (.) Lopération entraîne un débordement de pile et comme Bash ne sintègre pas avec libsigsegv , cela se traduit par un SIGSEGV.
Notez quil ne sagit pas dun bogue, mais dun comportement attendu, comme expliqué ici .
Test
./bang Segmentation fault (core dumped)
Réponse
Python 33
import os os.kill(os.getpid(),11)
Envoi du signal 11 (SIGSEGV) en python.
Commentaires
- Aussi 33 caractères:
from os import*
etkill(getpid(),11)
Réponse
C – 11 (19) 7 (15) 6 (14) 1 caractères, AT & Assembleur T x86 – 8 (24) caractères
La version C est:
*(int*)0=0;
Lensemble du programme (pas tout à fait ISO -compliant, supposons que K & RC) fait 19 caractères de long:
main(){*(int*)0=0;}
Assembleur variante:
orl $0,0
Lensemble du programme fait 24 caractères (juste pour lévaluation, car ce nest pas réellement un assembleur):
main(){asm("orl $0,0");}
EDIT :
Quelques variantes en C. Le premier utilise linitialisation à zéro de la variable de pointeur globale:
*p;main(){*p=0;}
Le second utilise la récursivité infinie:
main(){main();}
La dernière variante est la plus courte – 7 (15) caractères.
EDIT 2 :
A inventé une variante de plus qui est plus courte que nimporte laquelle des ci-dessus – 6 (14) caractères. Cela 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 de long:
P
Compilez-le simplement comme ça :
cc -o segv -DP="main(){main();}" segv.c
Commentaires
- en C isn ‘ t main; seulement 5 caractères
- : Linker ne ‘ t vérifie si main est une fonction ou non. Il le transmet simplement à le chargeur et retournent sigsegv
- @FUZxxl Dans ce cas,
main
est une variable int globale initialisée à zéro, donc ce que nous obtenons est suite à une tentative d’exécution de zéro octet. Dans x86, cela ‘ d être quelque chose commeadd %al,(%rax)
qui est une instruction parfaitement valide qui tente datteindre la mémoire à ladresse stockée dans%rax
. Les chances davoir une bonne adresse là-bas sont minimes. - 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. 🙂
- Habituellement, les indicateurs du compilateur autres que ceux qui choisissent la version linguistique à utiliser sont comptés dans le total.
Réponse
Perl, 10/12 caractères
Une solution un peu triche consiste à raser un caractère Joey Adams « bash trick :
kill 11,$$
Cependant, pour obtenir un vrai segfault en Perl, unpack p
est la solution évidente :
unpack p,1x8
Techniquement, ce nest pas garanti à segfault, puisque ladresse 0x31313131 (ou 0x3131313131313131 sur les systèmes 64 bits) pourrait indiquer un espace dadressage valide par hasard. Mais les chances sont contre elle. De plus, si perl est jamais porté sur des plates-formes où les pointeurs sont plus longs que 64 bits, le x8
devra être augmenté.
Commentaires
- Quest-ce que cest
1x8
? - @HannesKarppila Cest ‘ un raccourci pour écrire
"11111111".
Réponse
dc – 7 caractères
[dx0]dx
provoque un débordement de pile
Commentaires
- Cela fonctionne, mais pouvez-vous élaborer? Pourquoi se comporte-t-il de cette façon?
-
[dx0]
stockedx0
sur la pile, puisd
duplique lélément supérieur de la pile, puisx
fait apparaître lélément supérieur de la pile (dx0
) et lexécute. Ce qui duplique lélément supérieur de la pile et commence à lexécuter … le0
doit être là pour éviter quil ne sagisse dun appel de queue, donc ils se construisent tous.
Réponse
PicoLisp – 4 caractères
$ pil : ("0) Segmentation fault
Ceci est un 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 peut être appelé le « Scalpel of Programming « : Sharp, précis, petit et léger, mais aussi dangereux entre les mains des inexpérimentés.
Réponse
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
Commentaires
- Beau premier message.
Réponse
En fait , 17 16 11 10 9 octets
⌠[]+⌡9!*.
Si ce qui précède ne plante pas, essayez daugmenter le nombre (les nombres à plusieurs chiffres sont spécifiés dans En fait avec un signe deux-points )
Bloque linterprète r en exploitant un bogue en python impliquant des objets itertools.chain
profondément imbriqués, qui utilise en fait pour implémenter le +
opérateur.
Réponse
OCaml, 13 octets
Obj.magic 0 0
Ceci utilise la fonction Obj.magic
, qui contraint de manière non sécurisée deux types quelconques. Dans ce cas, il contraint 0 (stocké comme valeur immédiate 1, en raison du bit détiquette utilisé par le GC) à un type de fonction (stocké sous forme de pointeur). Ainsi, il essaie de déréférencer ladresse 1, et cela sera bien sûr une erreur de segmentation.
Commentaires
-
it coerces 0 (stored as the immediate value 1)
– pourquoi 0 est-il stocké comme 1? - @Skyler voir edit
-
Obj.magic()0
est un caractère plus court 🙂
Réponse
Pyth, 3 caractères
j1Z
Ce serait la partie où jexplique comment jai trouvé cette réponse, sauf que je nai légitimement aucune idée . Si quelquun pouvait mexpliquer cela, je vous en serais reconnaissant.
Le voici dans un interpréteur en ligne.
Explication
j
place la base au carré et sappelle elle-même de manière récursive 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écursivité suffisamment élevée, vous obtenez un segfault.
Commentaires
- Jai trouvé quelque chose! En parcourant la source de Pyth ‘, jai trouvé que ce code fait
j
sur1
et0
, qui essaie de convertir1
en base0
. Pourquoi ces segfaults, je nai pas idée … - Voir ici .
j
met au carré la base et sappelle lui-même 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 un segfault. - @Dennis IDEone
- @SeeRhino Linterpréteur Pyth définit la limite de récursivité sur 100 000. Au moins sur TIO, cela ‘ est suffisant pour une erreur de segmentation.
Réponse
C # – 62
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
C # / unsafe, 23 octets
unsafe{int i=*(int*)0;}
Pour une raison quelconque, je ne comprends pas, *(int*)0=0
lève simplement une exception NullReferenceException, alors que cette version donne la violation daccès appropriée.
Commentaires
- Le
int i=*(int*)0;
renvoie une NullReferenceException pour moi. - Vous pouvez essayer daccéder à un emplacement à exclure, comme
*(int*)-1=0
et obtenir une violation daccès. - Lexception particulière est exactement ce que le clr lenveloppe, et cest insignifiant. Le système dexploitation lui-même donne en fait lerreur de segmentation dans tous ces cas.
- La raison pour laquelle
*(int*)0=0
lève une exception est probablement due à loptimisation. Plus précisément, pour éviter le coût de la vérification denull
, l’optimiseur peut supprimer les vérifications nulles, mais quand une erreur de segmentation se produit, il peut la renvoyer en tant queNullReferenceException
.
Réponse
19 caractères en C
main(a){*(&a-1)=1;}
Il corrompt la valeur dadresse de retour de la fonction principale, donc il obtient un SIGSEGV au retour de main
.
Commentaires
- Cela dépend de la disposition du cadre de la pile, donc dans certaines architectures, cela ne peut pas échouer.
- Pourquoi pas simplement
main;
, oumain(){*""=0;}
? - @Sapphire_Brick
main;
est déjà indiqué dans une autre réponse. - @saeedn Alors pourquoi le poster? Celui-ci nest ‘ même que le deuxième au plus court!
- @Sapphire_Brick Au moment où je postais le mien,
main;
nétait ‘ t posté et je ne savais ‘ que cela fonctionne. Je faisais simplement remarquer que cest déjà donné et quil ne sert à rien de changer ma réponse. De plus, les gens ici ne ‘ ne publient que pour le plus court, parfois une autre façon de résoudre le problème est également intéressante.
Réponse
Cython, 14
Ceci est souvent utile à des fins de débogage.
a=(<int*>0)[0]
Réponse
J (6)
memf 1
memf
signifie mémoire libre, 1
est interprété comme un pointeur.
Commentaires
- Pourquoi
1
plutôt que0
? Est-il légal de libérer un pointeur nul dans J?
Answer
Matlab – Oui cest possible!
En réponse à ma question , Amro a trouvé cette bizarrerie:
S = struct(); S = setfield(S, {}, "g", {}, 0)
Commentaires
- Veuillez indiquer la version Matlab – R2015B (et 2016B également) lève simplement une erreur: Erreur lors de lutilisation de setfield (ligne 56) Au moins un index est obligatoire.
- @FlorianCastellane Impossible dessayer toutes les versions pour le moment, mais il a été confirmé quil donne une erreur de segmentation dans de nombreuses versions, la dernière étant 2014b et la plus ancienne 2012a.
Réponse
C – 14 caractères
Assurez-vous de compiler un fichier vide avec cc -nostartfiles c.c
Explication:
Ce qui ne va pas, cest que nous avons traité _start comme sil sagissait dune fonction C, et a essayé den revenir. En réalité, ce nest pas du tout une fonction. Cest juste un symbole dans le fichier objet que léditeur de liens utilise pour localiser le point dentrée du programme. Lorsque notre programme est appelé, il est appelé directement. Si nous devions regarder, nous verrions que la valeur en haut de la pile était le numéro 1, ce qui est certainement très différent de ladresse. En fait, ce qui est sur la pile est la valeur argc de notre programme. Après cela, viennent les éléments du tableau argv, y compris lélément NULL de fin, suivi des éléments denvp. Et cest tout. Il ny a pas dadresse de retour sur la pile.
Commentaires
- I ‘ m à peu près sûr que vous devez marquer avec les arguments supplémentaires
- Vous devez ajouter 14 octets pour lindicateur spécial.
- @ErikGolfer エ リ ッ ク ゴ ル フ ァ ー -nostartfiles est en fait 13 octets de long 🙂
- @CharlesPaulet Je pense que vous devez aussi compter lespace.
Réponse
Assemblage Unix PDP-11, 18 octets binaires, 7 octets source
(cela devient un thème avec moi, peut-être parce que cest le seul langage que je connais en quelque sorte non- un autre ici fait.)
inc(r0)
Incrémente loctet unique adressé par la valeur initiale de r0 [qui se trouve être 05162 selon le débogueur simh] à partir de démarrage 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.
Jai fait quelques tente de raccourcir la source, mais finit toujours par ge tting soit une erreur de syntaxe ou SIGBUS.