Quel est le code le plus court pour provoquer un débordement de pile? [fermé]

160

Pour commémorer le lancement public de Stack Overflow, quel est le code le plus court pour provoquer un débordement de pile? Toute langue est la bienvenue.

ETA: Juste pour être clair sur cette question, vu que je suis un utilisateur occasionnel de Scheme: la "récursion" de l'appel final est en fait une itération, et toute solution qui peut être convertie en une solution itérative de manière relativement triviale par un compilateur décent ne le sera pas Être compté. :-P

ETA2: J'ai maintenant sélectionné une «meilleure réponse»; voir ce post pour la justification. Merci à tous ceux qui ont contribué! :-)

Chris Jester-Young
la source

Réponses:

212

Toutes ces réponses et pas de Befunge? Je parierais pas mal que c'est la solution la plus courte de toutes:

1

Sans blague. Essayez-le vous-même: http://www.quirkster.com/iano/js/befunge.html

EDIT: Je suppose que je dois expliquer celui-ci. L'opérande 1 pousse un 1 sur la pile interne de Befunge et le manque de quoi que ce soit d'autre le met en boucle selon les règles du langage.

En utilisant l'interpréteur fourni, vous finirez par - et je veux dire par la suite - atteindre un point où le tableau Javascript qui représente la pile Befunge devient trop grand pour que le navigateur puisse se réallouer. Si vous aviez un interpréteur Befunge simple avec une pile plus petite et limitée - comme c'est le cas avec la plupart des langages ci-dessous - ce programme provoquerait un débordement plus visible plus rapidement.

Patrick
la source
8
Hmm… mais est-ce vraiment un débordement de pile ou juste une boucle infinie? Mon interprète JS n'a pas débordé, il est juste parti en vacances, pour ainsi dire.
Konrad Rudolph le
3
Ce n'est pas une boucle infinie, car l'instruction 1 pousse un 1 sur la pile. Finalement, votre interpréteur Befunge manquera d'espace dans la pile, mais cela prendra un certain temps. :)
Patrick
18
Vous… avez planté mon navigateur et… envoyé mon ventilateur de processeur en overdrive.
Sam152
2
Incroyable! Mon ordinateur ou navigateur (Opera) ne s'est pas planté mais les deux processeurs fonctionnaient à 100% et la vitesse du ventilateur était à 3.
Secko
28
Voici un programme Befunge qui déborde plus rapidement: " il charge 79 copies du numéro 32 toutes les deux fois qu'il s'enroule, plutôt que 2 copies du numéro 1.
KirarinSnow
291

Lisez cette ligne et faites ce qu'elle dit deux fois .

jrudolph
la source
174

Vous pouvez également essayer ceci en C # .net

throw new StackOverflowException();
GateKiller
la source
29
Le pédant en moi dit que cela ne provoque aucun débordement de pile, mais lève simplement une exception. C'est comme dire que le moyen le plus rapide d'être attaqué par des requins est de se tenir dans la mer et de crier "Shark attack!". Malgré cela, je voterai à la hausse. :)
Bernard
Eh bien, y a-t-il une différence? Pouvez-vous l'attraper et continuer? Ou est-ce exactement comme un stackoverflow en c #? Dans ce cas, il s'agit en quelque sorte d'un stackoverflow, car il est impossible de le distinguer d'un seul ... Cependant - vote pour toutes les raisons ci
Mo.
18
Si une pile déborde dans les bois sans personne pour attraper, cela lève-t-il une exception?
Je ne dirais pas le `` plus court '' car ce n'est pas comme si vous pouviez compiler un one-liner comme ça. Il fait jeter un débordement de pile rapidement si je suppose.
Dominic K du
159

Nemerle :

Cela plante le compilateur avec une exception StackOverflowException:

def o(){[o()]}
Cody Brocious
la source
119

Mon meilleur actuel (en assemblage x86) est:

push eax
jmp short $-1

ce qui donne 3 octets de code objet ( 50 EB FD). Pour le code 16 bits, cela est également possible:

call $

ce qui donne également 3 octets ( E8 FD FF).

Chris Jester-Young
la source
6
Compter les octets après "compilation" (ou assemblage) n'est pas du code-golf.
Louis Brandy
37
La question dit "[...] quel est le code le plus court pour provoquer un débordement de pile?" Il ne spécifie pas le code source, le code interprété, le code machine, le code objet ou le code managé ...
Anders Sandvig
Pour mémoire, le serveur de golf de Shin vous permet d'envoyer du code objet pour être jugé, bien qu'il comptera également tous vos en-têtes ELF. Hmm ....
Chris Jester-Young
Voir, par exemple, golf.shinh.org/p.rb?FizzBuzz#x86 pour quelques exemples de ceci. (Honnêtement, je ne sais pas comment les gens peuvent créer des binaires ELF de 99 octets.) :-P
Chris Jester-Young
7
@lbrandy: Il y a suffisamment de personnes qui peuvent écrire directement du code objet. Je ne peux pas le faire pour x86 mais pour un certain microprocesseur, je peux. Je compterais ce code.
Joey
113

PIC18

La réponse PIC18 donnée par TK entraîne les instructions suivantes (binaire):

overflow
   PUSH
   0000 0000 0000 0101
   CALL overflow
   1110 1100 0000 0000
   0000 0000 0000 0000

Cependant, CALL seul effectuera un débordement de pile:

CALL $
1110 1100 0000 0000
0000 0000 0000 0000

PIC18 plus petit, plus rapide

Mais RCALL (appel relatif) est encore plus petit (pas de mémoire globale, donc pas besoin des 2 octets supplémentaires):

RCALL $
1101 1000 0000 0000

Ainsi, le plus petit sur le PIC18 est une seule instruction, 16 bits (deux octets). Cela prendrait 2 cycles d'instructions par boucle. À 4 cycles d'horloge par cycle d'instruction, vous avez 8 cycles d'horloge. Le PIC18 a une pile de 31 niveaux, donc après la 32ème boucle, il débordera de la pile, en 256 cycles d'horloge. À 64 MHz, vous déborderiez la pile en 4 microsecondes et 2 octets .

PIC16F5x (encore plus petit et plus rapide)

Cependant, la série PIC16F5x utilise des instructions 12 bits:

CALL $
1001 0000 0000

Encore une fois, deux cycles d'instruction par boucle, 4 horloges par instruction donc 8 cycles d'horloge par boucle.

Cependant, le PIC16F5x a une pile à deux niveaux, donc sur la troisième boucle il déborderait, en 24 instructions. À 20 MHz, il déborderait en 1,2 micro seconde et 1,5 octets .

Intel 4004

L' Intel 4004 a une instruction de sous-programme d'appel 8 bits:

CALL $
0101 0000

Pour les curieux qui correspond à un ascii 'P'. Avec une pile à 3 niveaux qui prend 24 cycles d'horloge pour un total de 32,4 micro secondes et un octet . (Sauf si vous overclockez votre 4004 - allez, vous savez que vous voulez.)

Ce qui est aussi petit que la réponse befunge, mais beaucoup, beaucoup plus rapide que le code befunge exécuté dans les interpréteurs actuels.

Adam Davis
la source
77

C #:

public int Foo { get { return Foo; } }
aku
la source
57

Hoot trop-plein!

//              v___v
let rec f o = f(o);(o)
//             ['---']
//             -"---"-
Juliette
la source
55

Chaque tâche a besoin du bon outil. Découvrez le langage SO Overflow , optimisé pour produire des débordements de pile:

so
Konrad Rudolph
la source
7
Si vous créez un langage spécialisé pour générer des débordements avec un minimum de code, vous voudrez évidemment (1) une entrée vide produit du code de débordement de pile (probablement un petit binaire qui exécute le code natif généré à partir de l'entrée de code d'assemblage) ou (2 ) tous les programmes d'entrée produisent ledit binaire.
Jared Updike
Hmmm, pas Turing complet. Je ne sais pas si vous pouvez encore appeler cela une langue ...
Adam Davis
42

Texas:

\def~{~.}~

Résulte en:

! Capacité TeX dépassée, désolé [taille de la pile d'entrée = 5000].
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
~ -> ~
    .
...
<*> \ def ~ {~.} ~

Latex:

\end\end

Résulte en:

! Capacité TeX dépassée, désolé [taille de la pile d'entrée = 5000].
\ end # 1 -> \ csname end # 1
                      \ endcsname \ @checkend {# 1} \ expandafter \ endgroup \ if @ e ...
<*> \ end \ end
Pi.
la source
Comme ~est actif, il peut être utilisé à la place de \a. Et j'ai découvert le code LaTeX complètement par accident. :)
Josh Lee
35

Assembleur Z-80 - à l'emplacement de mémoire 0x0000:

rst 00

un octet - 0xC7 - boucle sans fin de poussée du PC actuel vers la pile et de saut à l'adresse 0x0000.

Dennis Munsie
la source
2
Je me souviens qu'un eprom vierge serait tous les 0xffs qui sont les 7 premières instructions (= appeler 0x0038). Cela serait utile pour déboguer votre matériel avec un oscilloscope. Le bus d'adresses parcourrait l'espace de 64 Ko lorsque la pile débordait à plusieurs reprises, entrecoupée de lectures de 0xff à partir de 0x0038.
Bill Forster
29

En anglais:

recursion = n. See recursion.
Vinko Vrsalovic
la source
32
Tout cerveau humain sensible optimisera également l'interprétation de celui-ci et ne fera pas exploser. :-P
Chris Jester-Young
73
Chris, les cerveaux humains sensés deviennent une rareté de nos jours.
Jason Z
20
rareté ... vous voulez dire qu'ils existent?
Adam Lerman
11
Google recursion
CodeFusionMobile
29

Un autre exemple PHP:

<?
require(__FILE__);
disq
la source
4
Vous pourriez même être court-circuité en sautant les parenthèses (mais en incluant un espace à la place du premier).
alex le
26

Que diriez-vous de ce qui suit en BASIC:

10 GOSUB 10

(Je n'ai pas d'interprète BASIC, je crains donc c'est une supposition).

stusmith
la source
3
Ce n'est pas vraiment un débordement de pile puisque BASIC est un langage sans pile. Même VB (qui a une pile) ne déborderait pas là-dessus car il ne fait que sauter, ne créant pas un cadre de pile.
Daniel Spiewak
21
C'est un GOSUB, pas un GOTO. Puisqu'il RETURNest de là où il a été appelé, il utilise sûrement une pile?
Tom
3
Oui je suis d'accord. J'ai eu de nombreux débordements de pile en BASIC dans les années 80.
nickd le
6
J'ai lancé celui-ci en yabasic juste pour le plaisir, et il a failli détruire mon ordinateur. Dieu merci, malloc a finalement échoué, mais je pageais comme pas de lendemain.
Adam Rosenfield
2
Oups désolé Adam ... me rappelle un moment à l'université où quelqu'un a accidentellement écrit un programme qui se dérobait de manière récursive: il a arrêté un serveur Silicon Graphics entier.
stusmith
26

J'ai adoré les tas de réponses de Cody, alors voici ma contribution similaire, en C ++:

template <int i>
class Overflow {
    typedef typename Overflow<i + 1>::type type;
};

typedef Overflow<0>::type Kaboom;

Pas une entrée de code de golf en aucun cas, mais quand même, quoi que ce soit pour un débordement de méta-pile! :-P

Chris Jester-Young
la source
21

Voici ma contribution C, pesant 18 caractères:

void o(){o();o();}

C'est beaucoup plus difficile à optimiser! :-P

Chris Jester-Young
la source
4
Ne compile pas pour moi: "référence indéfinie à" main "": P
Andrew Johnson
1
Je ne comprends pas: pourquoi appeler o () 2x?
Dinah
3
@Dinah: L'une des contraintes de mon concours était que l'optimisation des appels de fin ne compte pas comme une récursivité; c'est juste une boucle itérative. Si vous n'avez écrit o () qu'une seule fois, cela peut être optimisé pour les appels finaux en quelque chose comme ceci (par un compilateur compétent): "o: jmp o". Avec 2 appels de o, le compilateur doit utiliser quelque chose comme: "o: call o; jmp o". C'est l'instruction "appel" récursive qui fait déborder la pile.
Chris Jester-Young
Vous avez raison - je n'ai pas fait attention à cette partie. Merci pour la clarification.
Dinah
19

À l'aide du fichier de commandes d'une fenêtre nommé "s.bat":

call s
Jude Allred
la source
17

Javascript

Pour couper quelques caractères de plus et nous faire expulser de plus de boutiques de logiciels, allons-y avec:

eval(i='eval(i)');
Travis Wilson
la source
15

Sensationnel:

main()

$ groovy stack.groovy:

Caught: java.lang.StackOverflowError
    at stack.main(stack.groovy)
    at stack.run(stack.groovy:1)
 ...
Chris Broadfoot
la source
Voté parce que c'est assez intéressant. Expose une faiblesse plutôt ennuyeuse dans le compilateur Groovy (de tels appels de queue peuvent être intégrés au moment de la compilation).
Daniel Spiewak
êtes-vous sûr que c'est un appel de queue? que tomber la fin du programme n'invoque pas l'interpréteur shell?
Aaron
15

Veuillez me dire ce que signifie l'acronyme « GNU ».

Greg
la source
4
Ou Eine (Eine n'est pas Emacs), ou Zwei (Zwei était Eine au départ). :-P
Chris Jester-Young
Ou YAML, ou WINE, ou XNA, ou tout autre sur en.wikipedia.org/wiki/Recursive_acronym
TM.
Drei (Drei est vraiment Emacs Incognito), Fier (Fier est Emacs réinventé) - ok donc je viens de les inventer :-)
Ferruccio
14
Person JeffAtwood;
Person JoelSpolsky;
JeffAtwood.TalkTo(JoelSpolsky);

En espérant aucune récursion de queue!

Ryan Fox
la source
1
Hehe, drôle. En ce qui concerne les conversations, l'idée de «l'effet de chambre d'écho» est également très intéressante. Pas tout à fait induisant un débordement de pile, mais quand même.
Chris Jester-Young
8
Ne serait-ce pas une exception de pointeur nul? Désolé, je sais que c'est une blague.
jamesh
12

C - Ce n'est pas le plus court, mais il est sans récursivité. Ce n'est pas non plus portable: il plante sous Solaris, mais certaines implémentations d'alloca () peuvent renvoyer une erreur ici (ou appeler malloc ()). L'appel à printf () est nécessaire.

#include <stdio.h>
#include <alloca.h>
#include <sys/resource.h>
int main(int argc, char *argv[]) {
    struct rlimit rl = {0};
    getrlimit(RLIMIT_STACK, &rl);
    (void) alloca(rl.rlim_cur);
    printf("Goodbye, world\n");
    return 0;
}
bk1e
la source
Vous pouvez aussi simplement faire "ulimit -s16" pour définir la pile vraiment petite. Tout plus petit que 16 environ et le programme ne s'exécute même pas (args apparemment insuffisants!).
Andrew Johnson du
11

perl en 12 caractères:

$_=sub{&$_};&$_

bash en 10 caractères (l'espace dans la fonction est important):

i(){ i;};i
askol
la source
11

essayez de mettre plus de 4 galettes sur un seul hamburger. débordement de pile.

user8456
la source
1
Ici, en Nouvelle-Zélande, nous avons Burger Wisconsin, où ils utilisent de grosses mais fines galettes. Je suis sûr que vous pouvez en empiler plus de 4 si vous le souhaitez; ce sera un hamburger très cher cependant!
Chris Jester-Young
Mmm ... In-n-Out. en.wikipedia.org/wiki/In-n-out#Menu
cbednarski
11

Python :

so=lambda:so();so()

Alternativement:

def so():so()
so()

Et si Python optimisé tail appelle ...:

o=lambda:map(o,o());o()
Cody Brocious
la source
Heureusement pour vous, Python ne fait pas d'optimisation des appels de fin; sinon, il serait disqualifié comme deux autres réponses jusqu'à présent. :-P
Chris Jester-Young
10

Je sélectionne la «meilleure réponse» après cet article. Mais tout d'abord, je tiens à remercier quelques contributions très originales:

  1. ceux d'aku. Chacun explore une manière nouvelle et originale de provoquer un débordement de pile. L'idée de faire f (x) ⇒ f (f (x)) est celle que j'explorerai dans ma prochaine entrée, ci-dessous. :-)
  2. Celui de Cody qui a donné au compilateur Nemerle un débordement de pile.
  3. Et (un peu à contrecœur), celle de GateKiller sur le fait de lancer une exception de débordement de pile. :-P

Tout comme j'aime ce qui précède, le défi consiste à faire du golf codé, et pour être juste envers les répondants, je dois attribuer la «meilleure réponse» au code le plus court, qui est l'entrée Befunge; Je ne pense pas que quiconque puisse battre ça (bien que Konrad ait certainement essayé), alors félicitations Patrick!

Voyant le grand nombre de solutions de débordement de pile par récursivité, je suis surpris que personne n'ait (à l'heure actuelle) évoqué le combinateur Y (voir l'essai de Dick Gabriel, The Why of Y , pour une introduction). J'ai une solution récursive qui utilise le combinateur Y, ainsi que l'approche f (f (x)) d'aku. :-)

((Y (lambda (f) (lambda (x) (f (f x))))) #f)
Chris Jester-Young
la source
8

En voici un autre intéressant de Scheme:

((lambda (x) (xx)) (lambda (x) (xx)))
Adam Rosenfield
la source
Très joli, et il y a aussi une bonne symétrie. De plus, utiliser la formulation (lambda (x) (xx)): ((Y (lambda (x) (xx))) #f) est également très amusant!
Chris Jester-Young le
Oh, c'est joli. Cela fonctionne aussi dans Ruby, mais pas aussi joli que dans Scheme: lambda {| x | x.call x} .call lambda {| x | x.call x}
Wayne Conrad
7

Java

Version légèrement plus courte de la solution Java.

class X{public static void main(String[]a){main(a);}}
Misha
la source
5
Ou (même nombre de caractères): public static void main (String ... a) {main ();}
Michael Myers
Ou pour les types TDD (même nombre de caractères): public class ${@org.junit.Test public void $ () {$ ();}}
mhaller
Toujours pas le plus court (voir ma réponse)
Draemon
6
xor esp, esp
ret
a1k0n
la source
ce n'est pas vraiment un débordement de pile, mais c'est bien non plus: D
botismarius
5

3 octets:

label:
  pusha
  jmp label

Mettre à jour

D'après la (ancienne?) Documentation Intel (?) , C'est aussi 3 octets:

label:
  call label

Anders Sandvig
la source
C'est 3 octets en mode 32 bits. Bonne réponse, étant donné que cela remplira la pile beaucoup plus rapidement que ma réponse!
Chris Jester-Young
Selon penguin.cz/~literakl/intel/j.html#JMP , jmp est de 3 octets avec une adresse de destination relative de 8, 16 ou 32 bits. Le pusha fait également 1 octet, ce qui fait un total de 4
Anders Sandvig
Il existe trois types de jmp, court, proche et éloigné. Le jmp court (utilisant l'opcode 0xEB) est de deux octets. La destination doit être entre -128 et 127 octets de l'instruction suivante. :-)
Chris Jester-Young
Peut-être que tu as raison. Je suis trop paresseux pour déterrer mon assembleur et vérifier ...;)
Anders Sandvig