Zawieś swój ulubiony kompilator [zamknięty]

44

Napisz doskonale legalny kod w wybranym przez siebie dobrym języku, którego kompilacja albo zawiesi kompilator, albo wyśle ​​go do nieskończonej pętli (nieskończony czas kompilacji).

Ograniczenia:

  • Użyj standardowego języka, który jest używany w prawdziwym świecie.
  • Użyj standardowego, dobrze rozwiniętego kompilatora (brak odpowiedzi typu „Napisałem mój kompilator C, który ulega awarii na wszystkim”).
  • Kod musi być legalny w języku (więc najprawdopodobniej będziesz musiał wykorzystać kompilator lub błąd językowy).
  • Podaj wersję kompilatora i użyte opcje, aby inni mogli ją replikować.
  • Wyjaśnij, dlaczego kompilator się zawiesił, jeśli to możliwe.

Baw się dobrze :)

Petr Pudlák
źródło
4
Czy mógłbyś wyjaśnić, co rozumiesz przez „katastrofę”?
Pan Llama,
@GigaWatt Mam na myśli, że kompilator zatrzymuje się w niezamierzony sposób. Ani przez pomyślne skompilowanie danych wejściowych, ani przez wydanie komunikatu o błędzie. Musi się naprawdę upaść, jak segfault ,
pochłonięcie
1
Ten konkurs jest głównie ćwiczeniem polegającym na wyszukiwaniu raportów o błędach dla przypadków testowych: /
Sparr
1
Czy awaria tłumacza jest dozwolona?
Mark
1
Głosuj, aby ponownie otworzyć!
noɥʇʎԀʎzɐɹƆ

Odpowiedzi:

48

Moje ulubione rozwiązanie dla GHC:

data Bad a = C (Bad a -> a)

xx :: Bad a -> a
xx (x@(C x')) = x' x

omega :: a
omega = xx (C xx)

main = omega

Zarówno dla GHC 6.12.1, jak ghci Bad.hsi bez ghc Bad.hskońca zapętlają się. GHC 7.4.1 zapętla się nieskończenie po ghc -O2 Bad.hsuruchomieniu.

Objaśnienie: omega jest definiowany przy użyciu nieskończonej rekurencji (jedyny sposób, w jaki może on zamieszkać dowolny typ). Inliner kompilatora jest xxprostą, nierekurencyjną funkcją, więc próbuje wprowadzić go do definicji omega. To powoduje (\x@(C x') -> x' x) (C xx). Widząc dopasowanie wzorca na konstruktorze, kompilator próbuje go zmniejszyć, otrzymując xx (C xx)ponownie i zapętlając. Sztuczka polega na tym, że w xxrzeczywistości jest ona rekurencyjna, ale rekursja jest ukryta w typie danych.

Uwaga: podczas pisania układanki zapomniałem, że GHC działa w nieskończonej pętli. Zajęło mi to całą pamięć, rozbiło Firefoksa i ledwo udało mi się go zabić bez twardego resetu.

Petr Pudlák
źródło
5
+1 tylko za kłopot, przez który przeszedłeś odpowiedź: P
UnkwnTech
4
@UnkwnTech :-) Właściwie to odkryłem przez przypadek, gdy próbowałem zaimplementować rekurencję przy użyciu tylko rekurencyjnego typu danych.
Petr Pudlák,
18

Jest to łatwe w każdym języku zależnym od typu . Sprawdzanie typów ogólnych typów zależnych jest nierozstrzygalne, ponieważ może wymagać dowolnie złożonych obliczeń (Turing-complete). Możesz po prostu zakodować w typie zależnym zbyt dużą wartość. Następnie moduł sprawdzania typu wykorzysta całą dostępną pamięć i ulegnie awarii. Na przykład w Coq ReyCharles podaje przykładCompute 70000. , który powoduje, że moduł sprawdzania typu konstruuje gigantyczną liczbę Peano i ulega awarii.

W bardziej popularnych językach, które obsługują pewnego rodzaju ekspansję makr lub metaprogramowanie, możesz zrobić coś podobnego. Na przykład możesz użyć całej dostępnej pamięci w C:

#include <stdio.h>
#define a printf("%s", "Hello, world!\n");
#define b a a a a a a a a a a a a a a a a
#define c b b b b b b b b b b b b b b b b
#define d c c c c c c c c c c c c c c c c
#define e d d d d d d d d d d d d d d d d
#define f e e e e e e e e e e e e e e e e
// ...
#define z y y y y y y y y y y y y y y y y
int main() { z }

Język programowania D umożliwia wykonywanie funkcji czasu kompilacji . Można to wykorzystać do obliczenia czegoś, co w czasie kompilacji jest zbyt duże, aby zmieścić się w pamięci. Coś podobnego można osiągnąć za pomocą metaprogramowania szablonów C ++.

W języku XML (nieskompilowanym języku programowania, ale procesor XML jest analogiczny do kompilatora), rozwijanie jednostek może powodować brak pamięci procesora:

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
...
]>
<lolz>&lol999;</lolz>

Nazywa się to atakiem miliardów śmiechu .

Ślimak mechaniczny
źródło
4
Zauważ, że <lolz>&lol999;</lolz>śmieje się 10 999, a nie miliard. Powiązane odniesienia wykorzystują <lolz>&lol9;</lolz>, co w rzeczywistości jest miliardem.
mbomb007
Zauważ, że problem Coq nie ma nic wspólnego z kompletnością Turinga; System typów Coq jest specjalnie zaprojektowany, aby sprawdzanie typu było rozstrzygalne, a Turing nie zakończony. Sprawdzanie typu zawsze będzie możliwe przy stałej ilości pamięci (i zawsze się kończy), ale ta stała zależy od danego kodu i może być dowolnie duża.
John Colanduoni
18

DO#

Znaleziono to w pytaniu dotyczącym przepływu stosu :

using System;
using System.Linq;

public class Test
{
    public static void Main()
    {
        Enumerable.Range(0, 1).Sum(a =>
        Enumerable.Range(0, 1).Sum(b =>
        Enumerable.Range(0, 1).Sum(c =>
        Enumerable.Range(0, 1).Sum(d =>
        Enumerable.Range(0, 1).Sum(e =>
        Enumerable.Range(0, 1).Sum(f =>
        Enumerable.Range(0, 1).Count(g => true)))))));
    }
}

Kompilator ostatecznie się zawiesi.

Problem wydaje się dotyczyć wnioskowania typu i / lub generacji lambda w połączeniu z rozdzielczością przeciążenia.

Alberto
źródło
13
+1 za sprawienie, że inteligencja Visual Studio zużywa całą dostępną pamięć i powoduje awarię IDE. To jest wybryk, którego użyję tylko dla mocy dobra.
Mark
15

VBA

co powiesz na to, czy możesz zawiesić IDE, wpisując kod?

w dowolnej aplikacji Microsoft Office, spróbuj tego:

ALT+, F11aby przejść do okna VBA, a następnie wypróbuj następujący kod

sub foo()
dim v(1 to 3, 1 to 3)
redim preserve v(,1 to 5)

I oto:

Excel Death

Możesz po prostu wpisać redim preserve v(,1 to 5)w bezpośrednie okno, a po naciśnięciu zawiesi się ENTER!

SeanC
źródło
fajnie, ale bardziej jak „rozbić swojego ulubionego tłumacza”
mbx,
Czy mogę uzyskać krótkie podsumowanie, dlaczego to działa?
Pan Llama,
1
@GigaWatt, to omówione w małej głębokości więcej tutaj , ale wydaje się, że IDE nie może poradzić sobie z błędami (nieoczekiwane symbolem ,i oczekiwane ,)
SeanC
6

Perl (15)

BEGIN{1while 1}

To tworzy nieskończoną pętlę w czasie kompilacji :

Blok kodu BEGIN jest wykonywany tak szybko, jak to możliwe, czyli w momencie jego pełnego zdefiniowania, nawet przed przeanalizowaniem reszty pliku zawierającego (lub łańcucha).

(z perlmod )

I dlatego Perl nie jest w stanie dokończyć parsowania kodu. To nie kończy:

$ perl -MO=Deparse -e 'BEGIN{1while 1}'
memowe
źródło
5

jot

To powoduje awarię interpretera języka J (przynajmniej w systemie Linux):

15!:1[3#2

Próbuje czytać z adresu pamięci 2. Co ciekawe, jeśli spróbujesz z 0 lub 1, dostaniesz domain error.

marinus
źródło
5

TeX

\def\x{\x}\x

TeX jest językiem makropoleceń. Tutaj definiujemy rozszerzenie makra, \xaby było \xponownie, a następnie dodajemy wywołanie \x. TeX utknie w nieskończoność wymianie \xz \x.

Hammerite
źródło
2
Uwaga: nie jest to najkrótszy sposób na osiągnięcie tego. TeX ma pojęcie „aktywnych znaków”, które zasadniczo są znakami traktowanymi jak nazwy makr. Możesz więc ogolić z tego 3 postacie.
Hammerite
5

Schemat

(define-syntax s
    (syntax-rules ()
        ((_ (t) ...) (s (t t) ... (t t) ...))
        ((_ (t u) ...) (s (t) ... (u) ...))))
(s (+))

Mój kompilator, Chicken, popełnił błąd, próbując rozwinąć makra w czasie kompilacji dla „wydajności w czasie wykonywania” lub coś w tym rodzaju. Więc zapłacił cenę za rozszerzenie tego. Przeczytałem R5RS. Nikt nie powiedział, że makra musiały zostać rozszerzone w czasie kompilacji.

Zasadniczo to, co się dzieje, to makro rozwija się w ekspresję o nieskończonym rozmiarze, stale podwajając rozmiar. Cóż, żeby być technicznym, podwajając każde inne rozszerzenie. Los kompilatora jest przesądzony. Przynajmniej w moim systemie, czapki z kurczaka o pojemności 2 GB, długo się zatrzymują, próbując wyrzucić śmieci, a potem się zawieszają, gdy śmieciarz się poddaje. Zajmuje to jednak trochę czasu ze względu na całą kosztowną obliczeniowo higieniczną magię.

Przełączanie między wyrażeniami formularza

(s (+) (+) (+) (+) ....

i

(s (+ +) (+ +) (+ +) (+ +) ....

wydaje się bardzo, bardzo dramatycznie zwiększyć tempo zużycia pamięci w porównaniu do:

(define-syntax s
    (syntax-rules ()
        ((_ t ...) (s t ... t ...))))
(s +)

Podejrzewam, że Chicken jest dość odpornym kompilatorem, który ma pewne sposoby na uniknięcie dogłębnej analizy wyrażeń składniowych, kiedy może uciec, ale moje ostateczne rozwiązanie zmusza dopasowującego wzorzec do zagłębiania się.

unreproducable_butterfly
źródło
Łał +1 i zapraszamy do programowania puzzli i wymiany stosów kodów golfowych. Jeśli potrzebujesz pomocy lub po prostu chcesz porozmawiać, odpowiedz na ten komentarz @wizzwizz4.
wizzwizz4
3

Common Lisp

Makra ułatwiają:

(defmacro loop-forever ()
  (loop for x from 0 collecting x))

(defun compile-me ()
  (loop-forever))

Kompilowanie compile-mewywołań loop-forever, które wyczerpuje pamięć sterty podczas jej rozszerzania i powoduje awarię kompilatora. Jeśli chcesz, aby kompilator zawiesił się na czas nieokreślony, to loop-foreverzrobi to ta definicja :

(defmacro loop-forever ()
  (loop))

Powinno to działać przy użyciu dowolnej implementacji CL, chyba że twoja jest wyjątkowo sprytna i potrafi wykryć proste nieskończone pętle, ale poważnie wątpię, żeby to zrobiła. Oczywiście pełna ochrona przed tym jest niemożliwa.

Strigoides
źródło
meh Lisp sprawia, że ​​pisanie nieskończonych pętli w czasie kompilacji jest zbyt łatwe. Teraz, jeśli faktycznie rozbiłeś kompilator ...
John Dvorak
@JanDvorak Jedynym sposobem na załamanie Lisp jest wywołanie biblioteki C przez FFI ;-)
coredump
@coredump Proszę zrobić. W czasie kompilacji :-)
John Dvorak
(defmacro loop-forever () (loop)) (defun compile-me () (loop-forever))powinno wystarczyć. Wisi dla mnie CCL.
niania
3

PHP 5.3.1 (interpreter Segfaults) ( Bug 50261 , naprawiony w 5.3.3)

   test klasy Klasa
   {
       test testClass ()
       {
           echo 'Łańcuch wyjściowy!';
       }
   }

   klasa testClass2 rozszerza testClass
   {
       funkcja __construct ()
       {
           call_user_func (array ('parent', '__construct'));
       }
   }

   nowy testClass2;

Ten był trochę problemem, ponieważ powyższy kod był powszechny w wielu kodach, z którymi pracowałem, dzięki czemu jest to dla nas dość rozpowszechniony problem.

(Jeśli dobrze pamiętam, w pewnym momencie był to jedyny sposób wywoływania konstruktorów nadrzędnych w PHP).

Andrakis
źródło
3

re

(DMD32 D Compiler v2.067.1, kompilacja Windows)

enum x = "mixin(x);";
mixin(x);

Zauważ, że spowoduje to wysłanie kompilatora do nieskończonej pętli i zawieszenie go.

Błąd: brak pamięci

Mechaniczny ślimak zasugerował, że w tym celu można nadużywać funkcji programowania w czasie kompilacji w D, ale rozwiązanie jest być może prostsze niż techniki, które miał na myśli.


Dla tych, którzy nie są zaznajomieni z „miksami łańcuchowymi”, jest to dość prosta funkcja makr. Gdy kompilator napotka mixin("asdf"), zastępuje go zawartością ciągu asdfi próbuje go skompilować ponownie.

Powyższe rozwiązanie zostanie rozszerzone w następujący sposób:

mixin(x);  ->  mixin("mixin(x);");  ->  mixin(x);

Więc jeśli kompilator nie spróbuje wykryć tego przypadku rozwijania do tego samego, przejdzie do nieskończonej pętli rozszerzenia.

Kauterit
źródło
3

Perl

Definiuje to przeciążenie operatora w czasie kompilacji i uruchamia kod w czasie kompilacji, który dodaje instancje klasy razem.

(nawiasem mówiąc, normalnie nieskończona rekurencja zjadłaby całą pamięć, ale przy przeciążeniu po prostu ulega awarii)

package MyAmazingClass;
use 5.010;

use overload '+' => sub {
    my ($first, $second) = @_;
    return $first + $second;
};

sub new {
    my $self = shift;
    return bless {}, $self;
}

# BEGIN runs code at compile time
BEGIN {
    my $instance = MyAmazingClass->new;
    my $sum = $instance + $instance;
    say $sum;
}

Wynik:

fish: Job 1, 'perl' terminated by signal SIGSEGV (Address boundary error)
Konrad Borowski
źródło
3

Simplex v.0.5 , 2 bajty

Szkoda, że ​​to nie jest :

2Q

Pozwól mi wyjaśnić. Z dokumentów:

[ Q] Dodaje kod źródłowy programu do programu zewnętrznego, od początku (bez!! Znaków, jeśli bieżący bajt nie jest równy zero) Jeśli bajt ma wartość 2, duplikuje również bieżące polecenie.

Więc:

2 ~~ Manhattan adds 2 to the current byte: 10*0 + 2 = 2.
Q ~~ Adds program source code to the outer program, with Q

Zewnętrzny program jest fajną małą funkcją w Simplex: jest oceniany na końcu programu. Więc jeśli będziemy śledzić ...:

P1  P2  P3  P4  ...
2Q->2Q->2Q->2Q->...

W końcu skończy się pamięć i świat się skończy.

Conor O'Brien
źródło
3

Clang ++

Właśnie natknąłem się na ten zabawny błąd.

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

std::stringstream prog;

constexpr unsigned c_strlen( char const* str, unsigned count = 0 )
{
    return ('\0' == str[0]) ? count : c_strlen(str+1, count+1);
}

template < char t_c, char... tt_c >
struct rec_eval
{
    static void eval()
    {
        rec_eval<t_c>::eval();
        rec_eval < tt_c... > :: eval ();
    }
};
template < char t_c >
struct rec_eval < t_c >
{
    static void eval() {
        switch(t_c) {
            case '+':
                prog<<"++t[i];";
                break;
            case '-':
                prog<<"--t[i];";
                break;
            case '>':
                prog<<"++i;";
                break;
            case '<':
                prog<<"--i;";
                break;
            case '[':
                prog<<"while(t[i]){";
                break;
            case ']':
                prog<<"}";
                break;
            case '.':
                prog<<"putc(t[i],stdout);";
                break;
            case ',':
                prog<<"t[i]=getchar();";
                break;
        }
    }
};

template < char... tt_c >
struct exploded_string
{
    static void eval()
    {
        rec_eval < tt_c... > :: eval();
    }
};
template < typename T_StrProvider, unsigned t_len, char... tt_c >
struct explode_impl
{
    using result =
        typename explode_impl < T_StrProvider, t_len-1,
                                T_StrProvider::str()[t_len-1],
                                tt_c... > :: result;
};

template < typename T_StrProvider, char... tt_c >
struct explode_impl < T_StrProvider, 0, tt_c... >
{
     using result = exploded_string < tt_c... >;
};

template < typename T_StrProvider >
using explode =
    typename explode_impl < T_StrProvider,
                            c_strlen(T_StrProvider::str()) > :: result;


int main(int argc, char** argv)
{
    if(argc < 2) return 1;
    prog << "#include <stdio.h>\n#include <stdlib.h>\nint main(){unsigned char* t=calloc(";
    prog << (1 << sizeof(unsigned short));
    prog << ",sizeof(unsigned short));unsigned short i=0;";

    struct my_str_provider
    {
        constexpr static char const* str() { return "++++[>+++++<-]>+++[[>+>+<<-]>++++++[<+>-]+++++++++[<++++++++++>-]>[<+>-]<-]+++>+++++++++[<+++++++++>-]>++++++[<++++++++>-]<--[>+>+<<-]>>[<<+>>-]<-->>++++[<++++++++>-]++++++++++>+++++++++[>+++++++++++<-]>[[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.[<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.[<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<.>.[>]>[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<<<.>>>.<<<<.<.<<<<<<<<<<.>>>>>>.[>]<<.[<]>>>>>>>>>.>.>>>>>>>>>.[>]<<.<<<<<<<.[<]>>>>>>>>>.[<]>.>>>>>>>>>.[>]<<.<<<<.<<<<<<<<<<<<<.[>]<<<<<<<<<.[>]<<.[<]>>>>>>>>.[>]<<<<<<.[<]>>>>>..[>]<<.<<<<<<<<<<<<.[<]>>>>.[>]<<.<<<<.[<]>>>>>>.>>>.<<<<<<.>>>>>>>.>>>>>>>>>>.[>]<<<.>.>>>-[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<[>+>+<<-]>[<+>-]+>[<->[-]]<[-<<<[<]>>>>>>>>>>.<.[>]<<.[<]>>>>>>>>>>>.<<.<<<.[>]<<<<<<<<<<.[>]>>]<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]+>[<->-[<+>[-]]]<[++++++++[>+++++++++++++<-]>--.[-]<]<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.[<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.[<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<<.>>>..>>]"; }
    };

    auto my_str = explode < my_str_provider >{};
    my_str.eval();

    prog << "}";

    std::ofstream ofs(argv[1]);
    if(!ofs) return 2;
    ofs << prog.str() << std::endl;
    ofs.close();

    return 0;
}

Celem jest przetłumaczenie Brainfuck na C, przy użyciu meta-programowania szablonów, aby wykonać większość pracy. Ten kod działa dla mniejszych programów Brainfuck, takich jak Hello World, ale kiedy próbowałem uruchomić go z 99 butelkami ...

$ clang++ -std=c++11 -fconstexpr-depth=1000 bf_static.cpp
clang: error: unable to execute command: Segmentation fault (core dumped)
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 3.5.2 (tags/RELEASE_352/final)
Target: i386-pc-windows-cygnus
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/bf_static-afa982.cpp
clang: note: diagnostic msg: /tmp/bf_static-afa982.sh
clang: note: diagnostic msg:

********************

Z powodzeniem skompiluje się w GCC (po około 2 minutach), ale połączenie go powoduje inny problem ...

/usr/lib/gcc/i686-pc-cygwin/4.9.3/../../../../i686-pc-cygwin/bin/as: /tmp/cc0W7cJu.o: 
section .eh_frame$_ZN8rec_eval<giant mangled name removed>: string table overflow at offset 10004228
/tmp/cc3JeiMp.s: Assembler messages:
/tmp/cc3JeiMp.s: Fatal error: can't close /tmp/cc0W7cJu.o: File too big

Ups

Mego
źródło
3

Smalltalk (piskliwy dialekt, wersja 4.x)

Bardzo łatwo, po prostu oceń to, lub zaakceptuj metodę z tym dosłownym

1.0e99999999999999999999

Spróbuje ocenić moc 10 w arytmetyki dużej liczby całkowitej, tylko dla poprawnego zaokrąglenia inf Tsss;)

Edycja: ile 9 jest potrzebnych?

Ponieważ 2 ^ 10 wynosi 1024, około 10 ^ 3, możemy z grubsza przybliżać 10 ^ n przez 2 ^ (10 * n / 3). Oznacza to, że 10 ^ n wymaga 10 * n / 3 bitów do binarnego przedstawienia. Chcielibyśmy, aby 10 ^ n nie było reprezentatywne.

Zakładając 32-bitowe wskaźniki dla pamięci obiektów, wiemy, że nie możemy adresować więcej niż 2 ^ 32 bajty, czyli 2 ^ 35 bitów. Więc odwróćmy problem: 2 ^ 35 wynosi około 32 * 2 ^ 30, 32 * 10 ^ 9. Wymaga to około 11 cyfr dziesiętnych, więc z jedenastoma 9, z pewnością wygenerujemy błąd przy 32-bitowym pisku. W 64 bitach byłoby to dwadzieścia jeden 9.

Możemy również wyczerpać pamięć za pomocą mniejszych 9s, cała przestrzeń adresowalna niekoniecznie jest dostępna, ale testowanie jej jest śmiertelnie powolne, Squeak VM nie jest zoptymalizowany do tak gigantycznej arytmetyki w przeciwieństwie do GMP.

aka.nice
źródło
Potrzebujesz więcej niż czterech 9sekund?
Joe Z.
@JoeZ. tak, więcej niż 4 dziewiątki. Smalltalk ma arytmetykę LargeInteger, a maszyna ma teraz dużą pamięć RAM ... testowanie dokładnego limitu jest nudne, powyżej 6 dziewiątek kompilator zaczyna być
powolnywww
2

Oto moja oryginalna i zwięzła metoda na awarię GolfScript:

{1.}do

W ten sposób powstaje wieczna pętla, która ciągle wypycha 1 na stos aż do wyczerpania się pamięci.

W C / C ++ uważam, że ten oryginalny fragment kodu spowodowałby awarię kompilatora:

#define a bb
#define b aa
int main(){a}

Spowoduje to, że kompilator utknie podwojono liczbę a i zamieni je na b i odwrotnie, więc wkrótce kompilatorowi zabraknie pamięci i nastąpi awaria.

Innym jest wsadowy w systemie Windows, jeśli liczy się całkowicie zamrożenie komputera, a nie tylko sam skrypt wsadowy. Powinieneś wpisać następujące informacje:

:a
start %0
goto a

To wchodzi w nieskończoną pętlę robienia kopii siebie, które tworzą kopie siebie i tak dalej. Najprawdopodobniej doprowadziłoby to do awarii twojego komputera, gdybyś uruchomił ten kawałek kodu.

Ostatni jest bombą VBS. Jest to kolejna bomba, podobnie jak ostatnia, ale zamiast tego otwiera nieskończoną liczbę okien dialogowych.

set oshell = wscript.createobject("wscript.shell")
do
oshell.run "wscript " & wscript.scriptname
msgbox "blah"
loop

Powoduje to ciągłe tworzenie kopii samego siebie i otwiera okno komunikatu w nieskończonej pętli, co robią również klony. Uruchamianie tych dwóch ostatnich programów nie jest zalecane, ponieważ mogą one spowodować zawieszenie się komputera i konieczność twardego uruchomienia komputera.

Zauważ, że sam wymyśliłem wszystkie te programy.

Frederick
źródło
1
Makra C nie powtarzają się; nie można w ten sposób zawiesić preprocesora C lub C ++.
Joshua
2

Common Lisp, 8 bajtów

Krótszy niż inna odpowiedź Common Lisp :-)

#.(loop)

Pętla podczas czytania formularza.

Standard Common Lisp nie wspomina o przenośnym sposobie powodowania awarii, więc myślę, że musimy mieć sposób zdefiniowany w implementacji. Nadal 8 bajtów:

#.(quit) ; ccl

... lub

#.(exit) ; sbcl

Gdy dzwonisz (compile-file "crash.lisp"), środowiska w tajemniczy sposób „upaść”.

Żartując, wciąż próbuję znaleźć sposób, aby naprawdę zniszczyć środowisko (i wkrótce), ale to naprawdę trudne. Wszystko, co dostaję, to miła interakcja z debuggerem.

rdzeń rdzeniowy
źródło
2

x86 asm

„nasm -v” zwraca „NASM wersja 2.11.08 skompilowana 21 lutego 2015 r.” (Używam go pod Win7)

Asembler działa do tej pory na 1:12:27 na i7, całkowicie nasycając jeden z rdzeni. Plik wyjściowy ma 0 bajtów, zużycie pamięci jest stabilne na poziomie 1004K - wydaje się, że bezpiecznie jest powiedzieć, że pobiłem nasm, zamiast po prostu dać mu naprawdę, bardzo długie zadanie. :)

Kluczem do lewy jest powtórzenie wartości w makrze - 0xFFFFFFFF. Chociaż nie znam wystarczająco wewnętrznych elementów Nasm, aby wiedzieć, dlaczego dokładnie to dusi. Oczekiwałem, że otrzymam około 16 GB wyjścia godzinę temu.

%MACRO INVOKE 1-*
;  %REP    %0 - 1
  %REP     0xffffffff
    %ROTATE   -1
    PUSH    DWORD %1
  %ENDREP
  %ROTATE -1
  CALL    %1
%ENDMACRO

[section .text]
bits 32
org 0x10000

EntryPoint:
    INVOKE dword 666
    ret

EDYCJA: Właśnie sprawdziłem menedżera zadań, Nasm działa od 7:40:41, a pamięć jest teraz do 1016 KB

enhzflep
źródło
2

Asembler GNU, generujący ogromne pliki wyjściowe

To makro próbuje wypełnić plik wyjściowy śmieciami (zwykle bajty zerowe), dopóki nie zostanie osiągnięta granica 4 GB, dodaje liczbę całkowitą, aby przekroczyć tę granicę, i rekurencyjnie wywołuje siebie, aby nadal wypełniać dane wyjściowe kawałkami śmieci 4 GB. Spowoduje to zapełnienie dysku twardego, dopóki nie będzie pełny, w którym momencie asembler prawdopodobnie się zawiesi.

.macro f n #Define a macro named f, taking argument n.
.p2align 32 #Fill file with 0x00's until current address is divisible by 2^32
.long 0 #Add a long after the current address, throwing it off alignment.
.if \n #If n > 0, recursively tail-call itself, decrementing n.
f "(\n-1)"
.endif
.endm #End macro definition.
f 32 #Expand macro f, with n = 32 (output size 4GB*32 = 128GB)

Zauważ, że nie można użyć nieskończonej rekurencji, ponieważ asembler złapie ten specjalny przypadek i przestanie rozwijać makro.

Kompilacji można dokonać as -o crash.out crash.sw większości dystrybucji Linuksa.

maservant
źródło
Czy możesz skomentować źródło? Naprawdę nie rozumiem, co to robi.
kot
1
Powinieneś opublikować to jako odpowiedź na Zbuduj bombę kompilatora ! : D
cat
1

Common Lisp, 29 bajtów

Realizacja: Clozure CL

OSTRZEŻENIE: Zachowaj ostrożność podczas uruchamiania tego kodu, może zabić procesy, których nie chcesz!

#.(run-program"pkill"'("cl"))

Spowoduje to uruchomienie polecenia powłoki pkill clw czasie kompilacji, co zabije proces Lisp podczas kompilacji. Technicznie nie jest to awaria, ale ma ten sam efekt.

Przykładowe użycie:

$ cat /tmp/t.lisp
#.(run-program "pkill" '("cl"))
$ ccl -n
Welcome to Clozure Common Lisp Version 1.11-dev-r16513-trunk  (LinuxX8664)!

? (compile-file "/tmp/t.lisp")
#P"/tmp/t.lx64fsl"
NIL
NIL
?
zsh: terminated  ccl -n
$ 
niania
źródło
1

Felix

To już nie działa, ale w pewnym momencie ten kod:

include "std/control/pchannels";

fun is_square(v: int) => let s = int$ sqrt$ v.float + 0.5f in s*s == v;
fun is_median(v: int) => v % 4 == 0 and (v/4).is_square;

struct Message { value: int; };

proc process(c: int, chan: pchannel[Message]) {
    var i = 0;
    for var b in (c+1)/2 upto c do
        for var a in c - b + 1 upto b do
            if is_median(2*(b*b+c*c)-a*a) or
               is_median(2*(a*a+c*c)-b*b) or
               is_median(2*(a*a+b*b)-c*c) do ++i; done;
        done
    done
    write(chan, Message i);
};

proc main() {
    n := int$ System::argv 1;
    var count = n;
    chan := #mk_pchannel[Message];
    var ntri = 0;

    for var c in 1 upto n perform spawn_pthread { process(c, chan); };

    while count > 0 do
        let v = chan.read in ntri += v.value;
        --count;
    done
    ntri.println;
}

main;

Dałoby to duży błąd:

inner_bind_expression raised Not_found [BUG] e=(&((main_mf_60270<60270> ())), (value v))

BŁĄD SYSTEMU wyrażenie_wyrażenia 'podniesione Not_found [BŁĄD] Kompilacja Felixa "/ media / ryan / stuff / felix / build / release / host / bin / flxg" "-q" "--optimise" "--inline = 100" "- katalog_wyjściowy = / home / ryan / stuff / .felix / text "" - katalog_cache = / home / ryan / stuff / .felix / cache "" -I / media / ryan / stuff / felix / build / release / share / lib „” -I / media / ryan / stuff / felix / build / release / host / lib ”” --syntax=@/media/ryan/stuff/felix/build/release/share/lib/grammar/grammar.files ” „--automaton = / home / ryan / stuff / .felix / cache / media / ryan / stuff / felix / build / release / share / lib / grammar / grammar.files / syntax.automaton” ”--import = plat / flx.flxh "" std "" /home/ryan/golf/itri/sl.flx "nie powiodło się Błąd 1 we flx: [strerror_r] Nie można znaleźć tekstu dla błędu numer 1

Problem był tutaj:

let v = chan.read in ntri += v.value;

letspodziewałam się, że podąży za nim wyrażenie, ale zamiast tego wstawiłem oświadczenie. Tak więc kompilator trochę wystraszył.

Więcej informacji na https://groups.google.com/forum/m/#!topic/felix-language/J3Hs4j6E0gM .

kirbyfan64sos
źródło
1

JavaScript

while (true === true){
console.log(0);
}

To wysyła go w nieskończoną pętlę. Użyłem kompilatora Codecademy JS, który spowodował awarię przeglądarki.

juniorRubyist
źródło
1
Czy to powoduje awarię kompilatora lub środowiska wykonawczego? Przeglądarka internetowa zawiera oba te elementy, ale twierdzę, że nadal są to osobne elementy.
Hand-E-Food,
Kompilator się zawiesił, zamrażając moją przeglądarkę. @ Hand-E-Food
juniorRubyist
1
To nie powoduje awarii kompilatora; zawiesza twoją stronę. Możesz też po prostu pisać while(1){}; jest to również nieskończona pętla.
SirPython
Jeszcze krótszym przykładem jest while(1);.
Aplet123
1

JavaScript

function crash(){
  window.location.hash=Math.random(),onhashchange=function(){crash()}
}

Ten powoduje awarię przeglądarek internetowych w bardzo skuteczny sposób. UŻYWAJ NA WŁASNE RYZYKO !!!

Mama Fun Roll
źródło
3
Jaki jest dokładny sposób awarii? W szczególności to pytanie dotyczy awarii kompilatorów i wydaje się, że powoduje to śmierć przeglądarki, a nie wewnętrzny kompilator JS.
Petr Pudlák
FF odmawia awarii; uruchomienie tego w Chrome zawiesiło mój system.
kot
1

Potasu

Plik1 ma:

use "File2.has";

File2.has:

use "File1.has";

Powoduje to, że ładuje się i rozpoczyna kompilację pliku File2.has, co nakazuje mu załadowanie pliku File1.has, co powoduje załadowanie pliku File2.has i tak dalej.

Jacob Misirian
źródło
0

LOLCODE 1.2, LOLCODE Common Interpreter / Compiler (lci)

Wiem, że to nie jest ale i tak jest wyjątkowo krótki.

OBTW

To powoduje, że Signal 11:

Segmentation fault (core dumped)


Dlaczego? HAI1.2oznacza początek programu i OBTWinicjuje komentarz wielowierszowy. Ale kompilator spodziewa się KTHXBYE, aby zamknąć HAIi TLDRzamknąć wielowierszowego komentarza.

Zauważ, że to nadal będzie działać, powodując segfault z czymkolwiek innym niż TLDRpo OBTW.

(Zgodnie ze standardami wikipedii LOLCODE jest po prostu Dziwakiem, a nie ezoterycznym.)
Możesz pobrać tłumacza z git / justinmeza / lci .

kot
źródło
„Używaj standardowego języka używanego w prawdziwym świecie”. Chcesz mi powiedzieć, że użyjesz Lolcode do napisania legalnego programu?
Patrick Roberts,
@PatrickRoberts Tak, zrobiłbym to. / s
klaskać