스택 오버플로를 생성하는 가장 좋은 방법 [닫기]


146

프로그래머는 명백한 재귀로 인한 스택 오버플로의 오류를 확실히 알고 있습니다. 그러나 좋아하는 언어가 그 오류를 뱉어내는 데 이상하고 특이한 방법이 많이 있습니다.

목표 :

  1. 오류 출력에서 ​​명확하게 볼 수있는 스택 오버플로가 발생해야합니다.
  2. 명백한 재귀를 사용할 수 없습니다.

유효하지 않은 프로그램의 예 :

// Invalid, direct obvious recursion.
methodA(){ methodA(); }
// Invalid, indirect, but obvious recursion.
methodA(){ methodB(); }
methodB(){ methodA(); }

가장 는 가장 독창적 인 방법 입니다. 즉, 다음과 같은 명백한 대답을 피하십시오.

throw new StackOverflowError(); // Valid, but very boring and downvote-deserving.

지금 답변을 수락했지만 더 많은 답변을 추가해도 괜찮습니다. :)


14
선택한 검색 엔진에서 '스택 오버플로'를 쿼리하는 것으로 알려져 있지만 stackoverflow.com으로 이동하여 생성하는 경향이 있습니다.
OJFord

21
Internet Explorer를 사용하십시오. 하나를 잡는 확실한 방법 :)
asgoth February

64
스택 오버플로를 생성하는 가장 이상한 방법은 codegolf.stackexchange.com에 사람들이 스택 오버플로를 생성하는 가장 이상한 방법을 게시하도록 요청하는 인기 경연 대회를 게시하는 것입니다. 응답자는 질문에 대한 솔루션을 테스트 할 때 스택 오버플로를 발생시킵니다. 그래도 테스트하지 않았으므로 작동하는지 확신 할 수 없습니다 (그래서 답변으로 게시하지 않은 이유).
Tim Seguine

3
이 방법의 일부입니다 : joelonsoftware.com/items/2008/09/15.html
robert

11
도요타는 드라이브 (내 차이, 이봐, 잠깐 입니다 ... 도요타)
점잔 빼는 ossifrage

답변:


224

파이썬

import sys
sys.setrecursionlimit(1)

이렇게하면 통역사가 즉시 실패하게됩니다.

$ cat test.py
import sys
sys.setrecursionlimit(1)
$ python test.py
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e947b18> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e8f6050> ignored
$ 

재귀를 사용하는 대신 스택을 축소하여 즉시 오버플로합니다.


12
귀엽지 만 원래의 질문이 내 의견으로는 무엇을 목표로하고 있는지는 아닙니다.
Nit

12
@Nit 문제가 보이지 않습니다. 이 솔루션이 불만족스러운 것은 무엇입니까?
SimonT

17
@ masterX244 예, 질문의 요점은 "일반적인 방법으로하지 마십시오"입니다.
Plutor

24
@Plutor 일반적으로 StackOverFlow를 의도적으로 설정합니까?
Kiwy

15
이것이 처음 게시 될 때 이것은 약간 영리 했어요 .
primo

189

파이썬

import webbrowser
webbrowser.open("http://stackoverflow.com/")

7
환상적인. 멋지고 우아합니다.
James Webster

103
문자 그대로. 매우 대답합니다.
Tim Seguine

47
글쎄, 이것은 스택 오버플로를 보여 주지만 이것을 생성 하기 위해 Jeff Atwood 또는 Joel Spolsky가 실행하는 경우에만 작동합니다.
기계 달팽이

10
@TimSeguine 와우.
Sean Allred

9
오류 출력에 없으므로 답변이 아닙니다.
Pierre Arlaud

131

C / 리눅스 32 비트

void g(void *p){
        void *a[1];
        a[2]=p-5;
}
void f(){
        void *a[1];
        g(a[2]);
}
main(){
        f();
        return 0;
}

반환 주소를 덮어 쓰면 작동하므로 호출하기 전의 g시점으로 돌아갑니다 . 반송 주소가 스택에 있지만 조정이 필요할 수있는 모든 플랫폼에서 작동합니다.mainf

물론, 배열 외부에 쓰는 것은 정의되지 않은 동작 이며, 콧수염을 파란색으로 칠하는 것보다 스택 오버플로를 일으킬 것이라는 보장은 없습니다. 플랫폼, 컴파일러 및 컴파일 플래그의 세부 사항은 큰 차이를 만들 수 있습니다.


1
이것이 segfault를 생성하지 않습니까?
11684

4
이상한 스택 조작과 + 재귀에 +1!
RSFalcon7

6
@ 11684, 그것은 정의되지 않은 동작이므로 일반적으로 충돌 할 수 있습니다. 32 비트 Linux (내가 테스트 한)에서는 배열 외부에 쓰고 반환 주소를 덮어 쓰며 스택이 오버플로 될 때까지 충돌하지 않습니다.
ugoren

46
"당신의 콧수염을 파란색으로 칠하십시오"-> 그 줄은 저를 가졌습니다.
Aneesh Dogra

2
와. 이것은 환상적으로 난독 화됩니다.
MirroredFate

108

자바 스크립트 / DOM

with (document.body) {
    addEventListener('DOMSubtreeModified', function() {
        appendChild(firstChild);
    }, false);

    title = 'Kill me!';
}

브라우저를 죽이려면 콘솔에서 시도하십시오.


53
나는 당신이 더 많은 +1 투표를받을 자격이 있다고 확신하지만, 슬프게도 사람들은 투표하기 전에 이것을 시도했습니다 .... lol
Reactgular

5
글쎄, 그것은 효과적이었다. 작업 관리자를 열어서 죽일 수도 없었습니다.
primo

1
Chrome을 사용하고 탭을 닫습니다. 문제 해결됨.
Cole Johnson

1
with (document.body) { addEventListener('DOMSubtreeModified', function() { appendChild(firstChild); }, false); title = 'Kill me!'; } 15:43:43.642 TypeError: can't convert undefined to object
Brian Minton

1
젠장 내 Firefox가 중단되었습니다
Farhad

91

자바

여기 어딘가에 이와 같은 것을 보았습니다.

편집 : 내가 본 곳을 찾았습니다 : StackOverflow Error 를 발생시키는 가장 짧은 프로그램에 대한 Joe K의 답변

public class A {
    String val;
    public String toString() {
        return val + this;
    }

    public static void main(String[] args) {
        System.out.println(new A());
    }
}

일부 Java 초보자는 혼동 될 수 있습니다. 재귀 호출을 숨 깁니다. String 이기 때문에 val + this됩니다 .val + this.toString()val

여기에서 실행되는 것을 참조하십시오 : http://ideone.com/Z0sXiD


30
실제로, new StringBuilder().append(val).append("").append(this).toString()그리고 마지막 추가는 String.valueOf (...)를 호출하고 String.valueOf (...)를 호출합니다. 이렇게하면 스택 추적이 약간 달라집니다 (세 가지 방법).
Paŭlo Ebermann

2
@ PaŭloEbermann 그래, 맞아. 그러나 그것이된다고 말하는 것이 훨씬 쉽습니다 "" + this.toString().
저스틴

2
+ "" +언뜻보기에는 쓸모없는 것처럼 보이기 때문에 사람들에게 팁을 줄 수 있다고 생각합니다 . String val;그리고 return val + this;약간 비웃을지도 모른다
Cruncher

@Cruncher는 전혀 아닙니다. Java 코더 인 경우, ""-String 구성 중에 int를 문자열에 연결하는 쉬운 방법은+ ""
Justin

5
실제 응용 프로그램에서는 무한 재귀 및 스택 오버플로 오류를 피하는 것이
좋습니다

77

꽤 쉬운:

int main()
{
    int large[10000000] = {0};
    return 0;
}

10
명백하지 않은 경우 +1! 그것은 매우 시스템 의존적 임에도 불구하고 ( ulimit -s unlimited쉘에서 리눅스에서 이것을 해결합니다)
RSFalcon7

4
@ RSFalcon7, +1 주셔서 감사하지만 나에게 이것은 실제로 가장 분명했습니다!
Shahbaz

14
@Cruncher : 재귀를 일으키지 않습니다. 주어진 문제는 스택을 날려 버리는 것이었다. 많은 운영 체제에서 스택은 크기가 고정되어 있으며 천만 정수보다 훨씬 작으므로 스택이 손상됩니다.
Eric Lippert

2
@ HananBinder, 내가 테스트 한 Linux에서는 스택 오버플로 오류가 발생하지 않습니다. 스택 오버플로로 인해 소유하지 않은 세그먼트에 액세스 할 수 있으므로 세그먼트 오류가 발생합니다. 무한 재귀 함수 호출도 세그멘테이션 오류를 발생시키기 때문에 Linux에 스택 오버플로 오류가 있는지 확실하지 않습니다.
Shahbaz 2013

3
~0uC에서 꽤 큰 숫자입니다.
Vortico

63

C의 비 재귀 스택 오버플로

전화 컨벤션이 일치하지 않습니다.

typedef void __stdcall (* ptr) (int);

void __cdecl hello (int x) { }

void main () {
  ptr goodbye = (ptr)&hello;
  while (1) 
    goodbye(0);
}

로 컴파일하십시오 gcc -O0.

__cdecl함수는 호출자가 스택을 정리 __stdcall하고 수신자가이를 처리 할 것으로 예상하므로 typecast 함수 포인터를 통해 호출하면 정리가 수행되지 않습니다 main. 매개 변수를 각 호출에 대해 스택으로 푸시하지만 아무 것도 표시하지 않습니다. 스택 채우기.


2
스택을 스팸으로 보내는 좋은 방법 : P
masterX244

62

자바 스크립트

window.toString = String.toLocaleString;
+this;

5
이것은 저평가되었습니다.
Ry-

1
무엇을 +this합니까?
NobleUplift

8
단항 +는 ToNumber 추상 연산을 호출합니다. 힌트 유형의 숫자와 함께 ToPrimitive 연산을 사용합니다. 개체의 ToPrimitive는 [[DefaultValue]] 내부 메서드를 사용합니다.이 메서드는 숫자 힌트를 전달할 때 먼저 valueOf () 메서드가 있는지 확인하고 프리미티브를 반환합니다. window.valueOf ()는 객체를 반환하므로 [[DefaultValue]]는 toString ()을 호출 한 결과를 반환합니다. window.toString이 수행하는 첫 번째 작업 (현재 toLocaleString)은 'this'에서 toString을 호출합니다. 반복.
Ryan Cavanaugh

3
Chrome에서 '너무 많은 재귀'오류가 발생하면 Chrome에서 작동합니까? 스택 오버플로와 Chrome이 스택 오버플로 예외를 제공하는 방식입니다.
David Conrad

4
당신은 사용해야합니다 +{toString:"".toLocaleString}:-)
Bergi

62

Java 7과 java 8이 이전 답변 에서 사악한 코드에 면역된다는 사실에 좌절했습니다 . 그래서 그 패치가 필요하다고 결정했습니다.

성공! 나는 printStackTrace()던졌다 StackOverflowError. printStackTrace()디버깅 및 로깅에 일반적으로 사용되며 위험 할 수 있다고 합리적으로 의심하는 사람은 없습니다. 이 코드가 악용되어 심각한 보안 문제가 발생할 수 있음을 확인하는 것은 어렵지 않습니다.

public class StillMoreEvilThanMyPreviousOne {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        throw new EvilException();
    }

    public static class EvilException extends Exception {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}

어떤 사람들은 이것이 명백한 재귀라고 생각할 수도 있습니다. 그렇지 않습니다. EvilException생성자는 호출하지 않는 getCause()그 예외가 실제로 결국 안전하게 던져 질 수 있도록 방법을. getCause()메소드를 호출 해도 결과가 발생하지 않습니다 StackOverflowError. 재귀는 JDK의 일반적으로 의심되지 않는 printStackTrace()동작과 예외를 검사하는 데 사용되는 디버깅 및 로깅을위한 타사 라이브러리 내에 있습니다. 또한 예외가 발생하는 장소는 예외가 처리 된 장소와 매우 거리가 먼 것 같습니다.

어쨌든, 여기에 a를 던지고 StackOverflowError재귀 적 인 메소드 호출이 포함되지 않은 코드가 있습니다. 은 StackOverflowError외부 일 mainJDK의에서, 방법 UncaughtExceptionHandler:

public class StillMoreEvilThanMyPreviousOneVersion2 {
    public static void main(String[] args) {
        evilMethod();
    }

    private static void evilMethod() {
        throw new EvilException();
    }

    public static class EvilException extends RuntimeException {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}
Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "main"

2
: D 및 이제 크로스 Java 버전 스택 오버 플로우 호환 방법. 사악한 놈! : D
Kiwy

9
이 경우 재귀를 분명히 고려하는 경향이 있습니다.
Taemyr

1
@BlacklightShining getCause()메서드를 호출 해도 결과가 나타나지 않습니다 StackOverflowError. getCause()메소드를 재귀 적으로 호출하는 JDK 코드가 있다는 사실에 의존합니다 .
Victor Stafusa

2
본문 getCause을 그냥 변경하면 return this;Java를 너무 영리하게 바꿀 수 있습니다. " CIRCULAR REFERENCE" 임을 알 수 있습니다.
David Conrad

1
StackOverflowErrorjdk-1.7.0.21p2v0의 OpenBSD 5.5 패키지에 버그가 있기 때문에 나는 얻지 못했습니다 . 던지지 않습니다 StackOverflowError. 그것은 SIGSEGV핵심을 때리고 덤프합니다.
kernigh

57

리눅스 x86 NASM 어셈블리

section .data
    helloStr:     db 'Hello world!',10 ; Define our string
    helloStrLen:  equ $-helloStr       ; Define the length of our string

section .text
    global _start

    doExit:
        mov eax,1 ; Exit is syscall 1
        mov ebx,0 ; Exit status for success
        int 80h   ; Execute syscall

    printHello:
        mov eax,4           ; Write syscall is No. 4
        mov ebx,1           ; File descriptor 1, stdout
        mov ecx,helloStr    ; Our hello string
        mov edx,helloStrLen ; The length of our hello string
        int 80h             ; execute the syscall

    _start:
        call printHello ; Print "Hello World!" once
        call doExit     ; Exit afterwards

스포일러:

printHello에서 돌아 오는 것을 잊었으므로 다시 _start로 건너 뜁니다.


78
조립시에는 분명한 것이 없습니다.
11684

21
@ 11684 : 그 반대가 사실이라고 생각합니다. 어셈블리에서는 아무도 코드를 실제로 사용하여 추상화를 사용할 수 없기 때문에 모든 것이 분명합니다.
메이슨 휠러

3
단순함과 우아함이 훌륭합니다.
haneefmubarak

11
@MasonWheeler : 나는 모든 것이 명백한 것이 아니라 눈에 보이는 것이라고 말하는 것을 선호합니다 ... 보이는 것과 명백한 것의 차이점을 보는 좋은 방법은 underhanded.xcott.com
Olivier Dulac

2
잊어 버리는 실수를 자주 기억합니다ret
Ruslan

48

컴파일 타임에 C ++

template <unsigned N>
struct S : S<N-1> {};

template <>
struct S<0> {};

template
struct S<-1>;
$ g ++ -c test.cc -ftemplate-depth = 40000
g ++ : 내부 컴파일러 오류 : 분할 오류 (프로그램 cc1plus)
전체 버그 보고서를 제출하십시오.
적절한 경우 전처리 된 소스를 사용합니다.
지침을 참조하십시오.

이 소스 파일은 재귀가 없으며, 클래스 중 하나도 기본 클래스로 존재하지 않으며 간접적으로도 마찬가지입니다. (C ++ 이와 같이 템플릿 클래스, S<1>S<2>완전히 별개의 클래스이다.) 세그멘테이션 폴트 컴파일러 재귀 후 스택 오버 플로우에 기인한다.


7
나는 이것이 당신의 메타 프로그램에서 명백한 재귀라고 불렀을 것이라고 고백합니다.

2
GCC는 재귀를 감지하고이 쪽을 우아하게 멈 춥니 다 (4.8 이상은 괜찮은 것 같습니다)
Alec Teal

2
template <typename T> auto foo(T t) -> decltype(foo(t)); decltype(foo(0)) x;조금 더 짧습니다.
Casey

2
@hvd GCC의 버그를 이용하는 것 같습니다. clang은 잘못된 사용법을 포착 하지만 이미 알고 있다고 가정하지만 GCC는 거의 2 메가 바이트의 오류 메시지를 뿜어냅니다.
Casey


45

배쉬 (위험 경고)

while true
do 
  mkdir x
  cd x
done

엄밀히 말하면 오버플로를 직접 스택하지는 않지만 " 지속적인 스택 오버 플로우 생성 상황 " 합니다. 디스크가 가득 찰 때까지이를 실행하고 "rm -rf x ", 그 중 하나가 맞았습니다.

그러나 모든 시스템에서 발생하는 것은 아닙니다. 일부는 다른 것보다 강력합니다.

큰 위험 경고 :

어떤 시스템은 이것을 아주 잘 처리합니다 잘못 하므로 정리하기가 매우 어려울 수 있습니다 ( "rm -rf"자체가 recusion 문제가 발생하기 때문에). 정리를 위해 비슷한 스크립트를 작성해야 할 수도 있습니다.

확실하지 않으면 스크래치 VM에서이 방법을 사용하는 것이 좋습니다.

추신 : 물론 배치 스크립트로 프로그래밍하거나 수행하는 경우에도 마찬가지입니다.
PPS : 특정 시스템의 작동 방식에 대한 의견을 얻기 위해 방해가 될 수 있습니다.


내가 쓴 것처럼 : 많은 시스템에서 rm -rf는 다운하려고 시도하고 하나에 도달합니다 (더 이상 요즘은 64 비트 주소 공간이 없지만 더 작은 스택의 작은 컴퓨터에서는 더 낫습니다). 물론, "rm"구현이있을 수도 있는데, 다른 방식으로 ...
blabla999

2
나에게 while cd x; do :; done; cd ..; while rmdir x; cd ..; done;이것을 돌봐야 할 것 같습니다.
Blacklight Shining

당신은 절대적으로 옳습니다 (즉, "정리를위한 비슷한 스크립트"라는 의미입니다). 그러나 디스크 (또는 할당량)가 가득 차면 일부 시스템은 그 상황을 잘못 처리하는 데 사용되므로 나중에 로그인하기가 어려울 수도 있습니다. 루트로 들어가서 스크립트를 작성해야합니다 (오늘날 PC에서는 쉽지만 여러 사용자가 컴퓨터를 사용하는 고대에는 종종 힘들었습니다).
blabla999

재미 있고, 이것은 아래의 스몰 토크 마법보다 더 많은 표를 얻을 수 (그 생각하지 않았다!)
blabla999

누군가 Windows에서 이것을 시도 했습니까?
Sarge Borsch

43

자바

Java Puzzlers 의 멋진 것입니다 . 무엇을 인쇄합니까?

public class Reluctant {
    private Reluctant internalInstance = new Reluctant();

    public Reluctant() throws Exception {
        throw new Exception("I'm not coming out");
    }

    public static void main(String[] args) {
        try {
            Reluctant b = new Reluctant();
            System.out.println("Surprise!");
        } catch (Exception ex) {
            System.out.println("I told you so");
        }
    }
}

실제로 StackOverflowError와 함께 실패합니다.

생성자의 예외는 빨간 청어입니다. 이것은 책이 그것에 대해 말한 것입니다.

생성자를 호출하면 인스턴스 변수 이니셜 라이저가 생성자의 본문보다 먼저 실행 됩니다. 이 경우 변수의 이니셜 라이저 internalInstance가 생성자를 재귀 적으로 호출합니다. 그 생성자는 차례로 internalInstanceReluctant 생성자 등을 다시 호출하여 자체 필드를 초기화합니다 . 이러한 재귀 호출로 인해 StackOverflowError생성자 본문이 실행될 기회를 얻습니다. StackOverflowErrorError아닌 의 하위 유형 이므로 Exceptioncatch 절이 catch main하지 않습니다.


41

유액

\end\end

여기에\end 설명 된대로 반복적으로 무한 루프로 확장 되므로 입력 스택이 오버플 로 됩니다 .

TeX는 TeX capacity exceeded, sorry [input stack size=5000]이와 유사하거나 실패합니다 .


1
TeX / LaTeX 문제를 기다리고있었습니다. 그 것들이 가장 끔찍합니다. 일반적으로, 제가하는 일이 갑자기 재귀 적 인 것을 쓸 때 프로그래밍으로 간주한다는 것을 잊었습니다.
Ernir


1
"TeX 용량을 초과했습니다. 죄송합니다." TeX는 실패했을 때 매우 정중합니다.
Alex A.

40

BF

결국 스택을 오버플로 할 것입니다. 인터프리터가 스택을 만드는 시간에 달려 있습니다 ...

+[>+]

5
그 코드는 나에게 인생의 게임을 생각 나게한다.
아담 아 롤드

10
엄밀히 말하면, brainfuck에는 스택이 없습니다.
페예 쇼코

6
당신이 원한다면 @fejesjoco 테이프.
Timtech

32

컴파일 타임에 C #

Microsoft C # 컴파일러가 스택을 날려 버리는 방법에는 여러 가지가 있습니다. C # 컴파일러의 "표현식이 너무 복잡하여 컴파일 할 수 없습니다"라는 오류가 표시 될 때마다 스택이 손상 되었기 때문에 거의 확실합니다.

파서는 재귀 적하이므로 충분히 깊게 중첩 된 언어 구조가 스택을 날려 버립니다.

 class C { class C { class C { ....

표현식 파서는 일반적으로 재귀되는 측에서 재귀를 제거하는 것에 대해 매우 영리합니다. 보통:

x = 1 + 1 + 1 + 1 + .... + 1;

엄청나게 깊은 구문 분석 트리를 빌드하면 스택을 날려 버리지 않습니다. 그러나 다른 쪽에서 재귀를 강제로 수행하면 :

x = 1 + (1 + (1 + (1 + ....+ (1 + 1))))))))))))))))))))))))))))))))))))))))))...;

그런 다음 스택을 날릴 수 있습니다.

이것들은 프로그램이 매우 크다는 우아한 특성을 가지고 있습니다. 또한 시맨틱 분석기가 작은 시스템으로 무한한 재귀로 들어가는 것이 가능합니다. 유형 시스템에서 특정 홀수주기를 제거하기에 충분히 영리하지 않기 때문입니다. (Roslyn이이를 개선 할 수 있습니다.)

public interface IN<in U> {}
public interface IC<X> : IN<IN<IC<IC<X>>>> {}
...
IC<double> bar = whatever;
IN<IC<string>> foo = bar;  // Is this assignment legal? 

이 분석이 왜 무한 재귀로 진행되는지 설명합니다.

http://blogs.msdn.com/b/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx

더 많은 흥미로운 예를 보려면이 백서를 읽어야합니다.

http://research.microsoft.com/en-us/um/people/akenn/generics/FOOL2007.pdf


2
정확한 오류 메시지는 fatal error CS1647: An expression is too long or complex to compile near (code)입니다. 이 오류 메시지에 대한 설명서는 here 이며 "컴파일러에서 코드를 처리하는 동안 스택 오버플로가 발생했습니다."
bwDraco

32

인터넷에서 (일일 수십억 명의 사람들이 사용)

Redirects, HTTP status code: 301

예를 들어, Dell 지원 웹 사이트에서 (공격 없음, Dell 죄송)

URL에서 지원 TAG를 제거하면 무한 리디렉션됩니다 . 다음 URL에서 ######은 지원되는 TAG입니다.

http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/######?s=BSD&~ck=mn

스택 오버플로와 동일하다고 생각합니다.


5
좋은 방법은 : 파이어 폭스는 그렇게 요청이 유래의 rquivalent : 어떤 해결 될 수없는 리디렉션 있음을 알려줍니다
masterX244

3
리디렉션은 무한 하지 않습니다. "다시 시도" /Errors/를 누르면 URL에 몇 개 더 추가 한 다음 HTTP 400 잘못된 요청을받은 후 중지됩니다. 그러나 이것은 무한 리다이렉션보다 더 나은 스택 오버플로를 만듭니다.
nandhp

@ nandhp, 동의하지만, 최신 브라우저, IE 등이 아닌 제 3 세계 브라우저를 생각한다면 그들은이 상황에 대한 단서가 없습니다.
codeSetter

2
Wget의 응답 방식은 다음과 같습니다. pastebin.com/pPRktM1m
bwDraco

1
http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/...
Vortico

31

PHP

루핑 요소로만 수행되는 스택 오버 플로우입니다.

$a = array(&$a);
while (1) {
    foreach ($a as &$tmp) {
        $tmp = array($tmp, &$a);
    }
}

설명 (스포일러를 보려면 마우스를 가져 가십시오) :

인터프리터가 $tmp배열 을 가비지 수집하려고 할 때 ( $tmp여기에서 재 할당 할 때) 프로그램은 segfault 입니다. 배열이 너무 깊어서 (자체 참조) 가비지 수집기가 재귀로 끝납니다.


16
PHP의 GC가 자기 참조 구조를 감지 할 수 없습니까? 정말?! 아야. 즉 이다 악.
Peter C

1
예,하지만 완벽하지는 않습니다. 왜 while (1) { $a = array(&$a); }또는 비슷한 것이 메모리 제한에 도달 했는지 몇 가지 이유가 있습니다 .
bwoebi

네, PHP가 객체 지향 개발과 관련하여 제대로 작동하지 않는 이유와 같습니다. (추상화, 상속 등)
pythonian29033

1
@ pythonian29033 정교한 관리가 필요하십니까?
vvondra

30

자바

나는 분명히 스택 오버플로 오류를 발생시켜야하지만 그렇지 않은 프로그램과 정반대를했습니다.

public class Evil {
    public static void main(String[] args) {
        recurse();
    }

    private static void recurse() {
        try {
            recurse();
        } finally {
            recurse();
        }
    }
}

힌트 : 프로그램은 O (2 n ) 시간에 실행되며 n 은 스택 크기 (일반적으로 1024)입니다.

에서 자바 퍼즐 러 (Puzzler) # 45 :

우리 기계 가 초당 10 10 호출을 실행 하고 초당 10 10 예외를 생성 할 수 있다고 가정합시다 . 이는 현재 표준에 따라 상당히 관대합니다. 이러한 가정하에 프로그램은 약 1.7 × 10 291 년 후에 종료됩니다 . 이 관점에서 태양의 수명은 10 10 년으로 추정 되므로이 프로그램이 끝나는 사람은 아무도 없을 것입니다. 무한 루프는 아니지만 그럴 수도 있습니다.


3
명백한 재귀 ...별로 흥미롭지 않습니다.
Kami

5
@Kami 사용해 보셨습니까? 실제로 StackOverflowError가 발생 했습니까? 분명해 보이지만 그렇지 않습니다.
ntoskrnl

예외가 발생했다고해서 결코 발생하지 않았다는 의미는 아닙니다. 이 프로그램은 시간 O (n) 이후에 스택 오버플로 예외를 발생
시킵니다.

1
@CodesInChaos 좋아, 그래서 이것을 다시 확인했고 올바른 버전이 finally아닌을 사용 catch하고 실행 시간은 O (2 ^ n)입니다. 답변이 업데이트되었습니다.
ntoskrnl

@ntorkrnl 좋은 것 + 1'd; btw는 이미 컴파일러를
스택 오버 플로우로 가져 왔습니다

30

씨#

첫 번째 게시물이므로 나에게 쉽게 가십시오.

class Program
{
    static void Main()
    {
        new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Invoke(null, null);
    }
}

이것은 단순히 스택 트레이스를 생성하고 최상위 프레임 (마지막 호출 Main())을 가져 와서 메소드를 가져 와서 호출합니다.


설명 없이는 분명하지 않은 좋은 selfinvoke 방법; +
1'd

"무엇이 잘못 될 수 있는가?"로 해당 코드를 주석 처리해야합니다. : P
Spaceman

26

자바

  • Java 5에서는 printStackTrace()무한 루프를 시작합니다.
  • Java 6에서는을 printStackTrace()던집니다 StackOverflowError.
  • Java 7 및 8에서는 수정되었습니다.

미친 것은 Java 5와 6에서 사용자 코드에서 오는 것이 아니라 JDK의 코드에서 발생한다는 것입니다. printStackTrace()실행하기에 위험 할 수있는 합리적인 용의자는 없습니다 .

public class Bad {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        Exception a = new Exception();
        Exception b = new Exception(a);
        a.initCause(b);
        throw a;
    }
}

7
네; 아무것도없는 stackoverflow는 codetrolling의 가장 친한 친구이자 사냥에 심각한 두통이 있습니다
masterX244

2
궁금한 점이 있으면 C #의 동등한 코드로 인해 무한 루프가 발생합니다. 그러나 InnerException속성은 읽기 전용이며 생성자에서 설정되므로이를 반영하려면 리플렉션이 필요합니다.
Athari

17

자바 스크립트 : 비 재귀, 반복 함수 돌연변이

var f = function() {
    console.log(arguments.length);
};

while (true) {
    f = f.bind(null, 1);
    f();
}

여기에는 전혀 재귀가 없습니다. 단일 함수 호출에서f 스택 오버플로 할 수있을 때까지 점점 더 많은 인수로 반복적으로 커리됩니다 . console.log부분은 경우에 당신이 그것을하는 데 걸리는 얼마나 많은 인수보고 싶어 선택 사항입니다. 또한 영리한 JS 엔진이이를 최적화하지 않도록합니다.

CoffeeScript의 코드 골프 버전, 28 자 :

f=->
do f=f.bind f,1 while 1

14

서사시 실패와 C #

using System.Xml.Serialization;

[XmlRoot]
public class P
{
    public P X { get { return new P(); } set { } }
    static void Main()
    {
        new XmlSerializer(typeof(P)).Serialize(System.Console.Out, new P());
    }
}

그것이 실패하는 방식은 서사시이며, 내 마음이 완전히 불었습니다.

여기에 이미지 설명을 입력하십시오

그것은 겉보기에는 무한대로 넘어지는 일련의 이상한 이미지의 한 프레임에 불과합니다.

이것은 가장 이상한 일이되어야합니다. 아무도 설명 할 수 있습니까? 분명히 들여 쓰기에 사용되는 공간이 계속 늘어 나면 흰색 블록이 나타납니다. .NET 4.5가 설치된 Win7 Enterprise x64에서 발생합니다.

나는 실제로 아직 끝을 보지 못했습니다. 당신이 바꿀 경우 System.Console.OutSystem.IO.Stream.Null, 그것은 꽤 빨리 죽는다.

설명은 매우 간단합니다. 단일 속성을 가진 클래스를 만들고 항상 포함 유형의 새 인스턴스를 반환합니다. 그래서 그것은 무한히 깊은 객체 계층입니다. 이제 우리는 그것을 통해 읽을 수있는 무언가가 필요합니다. 그것이 내가 사용하는 곳 XmlSerializer입니다. 분명히 재귀를 사용합니다.


네; 직렬화 ftw : P; 그러나 더 재미있는 것은 ythe quirk가 snakeyaml이 속성을 얻는 방법과 같이 클래스가 완전히 재귀하는 방식과 같이 코드 외부에있을 때입니다.
masterX244

1
글쎄, 오버플로는 내 코드 외부에서 발생하지만 내가 게시 한 실제 이유는 콘솔의 예기치 않은 부작용 때문입니다 :-)
fejesjoco

.Net 4 (cmd를 통해 실행될 때조차도)를 사용하면 공백 만 있고 흰색 블록은 없기 때문에 흰색 비트는 .Net 4.5와 관련이 있거나 환경 설정 방법과 관련이 있어야한다고 생각합니다. 내 생각에 Win7 Enterprise 버전의 cmd 또는 .Net 4.5 콘솔 에뮬레이터는 특정 문자 조합을 '콘솔 색상 배경 ​​변경'으로 처리합니다.
Pharap

Aero가 켜진 Win7 x64 Professional에서 .NET 4.5로 재현 할 수 없음
Ray

또한 재현 할 수 없습니다. .NET 4.5, Windows 8.1 Pro.
bwDraco

13

세게 때리다

_(){ _;};_

많은 사람들이 재귀가 명백 하다는 것을 인식 할 수는 있지만 꽤 좋아 보입니다. 아니?

실행하면 다음을 볼 수 있습니다.

Segmentation fault (core dumped)

5
이것은 더 예쁘고 나쁘다 :_(){_|_;};_
RSFalcon7

1
@ RSFalcon7 포크 폭탄 경고! (또한 {구문 적으로 정확하기 위해 공백이 필요하지 않습니까?)
Shining

3
뿐만 아니라이 시도:(){:|:;}:
타렉 Eldeeb에게

14
소름 끼치는 돌연변이 이모티콘처럼 보입니다.
Tim Seguine

8
배쉬 이모티콘 : 얼굴 먹는 사람, 스택 킬러.
NobleUplift

12

하스켈

(슬프지만 사실까지 적어도 ghc-7.6와 비록 O1멀리 문제를 최적화 할 수 있습니다 이상)

main = print $ sum [1 .. 100000000]

테일 콜 최적화를 자동으로 수행하면 안됩니까?
blabla999

2
@ blabla999 : 테일 콜은 Haskell과 관련이 없으며, 이러한 문제를 일으키는 은밀한 게으름으로 인해 주로 썽크가 발생합니다. 이 경우 꼬리 호출을 사용하는의 sum관점에서 구현 foldl되지만 문제는 누산기를 평가하지 않기 때문에 원래 목록만큼 큰 덩어리가 생성됩니다. 로 전환하면 문제가 사라지고 foldl' (+)엄격하게 평가되므로 테일 호출에서 WHN을 반환합니다. 또는 내가 말했듯이 GHC의 최적화를 켜면!
반 시계 회전을 중단

aah-흥미 롭다. 만약 아무도 썽크를 기다리지 않는다면 (즉, 인쇄물을 남기지 않는다면) 가비지 수집기는 그것들을 앞뒤로 모을 것이다.
blabla999

1
BTW,이 중 어느 것도 Haskell 표준에 의해 실제로 지정되지 않았습니다. 평가가 엄격 하지 않아도됩니다. 즉 , 결과가 완전히 필요하지 않은 경우 비 종료 계산은 영원히 차단 되지 않습니다. 실제로 차단하는 시간은 구현에 달려 있으며 표준 게으른 GHC에서는 결과를 요청할 때까지 전혀 차단되지 않습니다.
반 시계 회전을 중단

2
하스켈은 멋지다.
blabla999

12

잡담

이렇게하면 새 메서드가 즉석에서
  만들어져 새 메서드가 즉석에서
    만들어져 새 메서드가 즉석에서 만들어 져서
      ...
    ...
  ..
로 전송됩니다.

더 작은 향신료는 스택 메모리와 힙 메모리를 동시에 강조하면서 더 길고 더 긴 메소드 이름과 수신자로 엄청난 수를 만들어서 구멍을 내릴 때 수신기로 엄청난 숫자를 가져옵니다 ... ).

정수로 컴파일 :

downTheRabbitHole
    |name deeperName nextLevel|

    nextLevel := self * 2.
    name := thisContext selector.
    deeperName := (name , '_') asSymbol.
    Class withoutUpdatingChangesDo:[
        nextLevel class 
            compile:deeperName , (thisContext method source copyFrom:name size+1).
    ].
    Transcript show:self; showCR:' - and down the rabbit hole...'.
    "/ self halt. "/ enable for debugging
    nextLevel perform:deeperName.

잠시 후 "2 downTheRabbitHole"...
... 을 평가하여 점프 하면 디버거가 끝나고 RecursionException이 표시됩니다.

그런 다음 모든 엉망을 정리해야합니다 (SmallInteger와 LargeInteger는 이제 많은 원더 랜드 코드를 갖습니다).

{SmallInteger . LargeInteger } do:[:eachInfectedClass |
    (eachInfectedClass methodDictionary keys 
        select:[:nm| nm startsWith:'downTheRabbitHole_'])
            do:[:each| eachInfectedClass removeSelector:each]

또는 브라우저에서 앨리스의 원더 랜드를 제거하면서 시간을 보내십시오.

다음은 추적 헤드의 일부입니다.

2 - and down the rabbit hole...
4 - and down the rabbit hole...
8 - and down the rabbit hole...
16 - and down the rabbit hole...
[...]
576460752303423488 - and down the rabbit hole...
1152921504606846976 - and down the rabbit hole...
2305843009213693952 - and down the rabbit hole...
[...]
1267650600228229401496703205376 - and down the rabbit hole...
2535301200456458802993406410752 - and down the rabbit hole...
5070602400912917605986812821504 - and down the rabbit hole...
[...]
162259276829213363391578010288128 - and down the rabbit hole...
324518553658426726783156020576256 - and down the rabbit hole...
[...]
and so on...

추신 : 스몰 토크의 지속적인 변경 로그 파일을 나중에 정리할 필요가 없도록 "withoutUpdatingChangesFile :"이 추가되었습니다.

PPS : 도전에 대한 감사 : 새롭고 혁신적인 무언가에 대해 생각하는 것이 재미있었습니다!

PPPS : 일부 스몰 토크 방언 / 버전은 넘쳐나는 스택 프레임을 힙에 복사하므로 메모리 부족 상황이 발생할 수 있습니다.


2
순수한 형태의 흑 마법에 대한 LOL +1
masterX244

시간이 있으면 익명 클래스의 익명 메소드를 사용하여 가장 어두운 토끼 구멍을 만들어 "개선"할 수 있습니다.
blabla999

12

씨#

정말 크고 struct재귀가 없으며 순수한 C #이며 안전하지 않은 코드는 아닙니다.

public struct Wyern
{
    double a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Godzilla
{
    Wyern a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Cyclops
{
    Godzilla a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Titan
{
    Cyclops a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Titan();
        // 26×26×26×26×8 = 3655808 bytes            
        Console.WriteLine("Size={0}", Marshal.SizeOf(A));
    }
}

키커로서 디버그 창에 충돌을 일으켜 {Cannot evaluate expression because the current thread is in a stack overflow state.}


그리고 일반 버전 (NPSF3000 제안에 감사드립니다)

public struct Wyern<T>
    where T: struct
{
    T a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;        
}


class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Wyern<Wyern<Wyern<Wyern<int>>>>();
    }
}

더 일반적인 코드
메타 크림이

재귀처럼 보이지만 중첩 된 형식 인수로 가능합니다.
ja72

1
내가 게시하기 전에 C # 구조체 응답을 보지 못했습니다. 나는 여전히 조금 다른 접근법을 가지고 있기 때문에 우리는 그것들을 공존시킬 수 있습니다.
Thomas Weller

11

씨#

재정의 ==연산자 의 잘못된 구현 :

public class MyClass
{
    public int A { get; set; }

    public static bool operator ==(MyClass obj1, MyClass obj2)
    {
        if (obj1 == null)
        {
            return obj2 == null;
        }
        else
        {
            return obj1.Equals(obj2);
        }
    }

    public static bool operator !=(MyClass obj1, MyClass obj2)
    {
        return !(obj1 == obj2);
    }

    public override bool Equals(object obj)
    {
        MyClass other = obj as MyClass;
        if (other == null)
        {
            return false;
        }
        else
        {
            return A == other.A;
        }
    }
}

운영자 operator==를 사용하여 자신 을 호출 하는 것이 분명 ==하지만 일반적으로에 대해 ==그렇게 생각하지 않으므로 해당 함정에 빠지기 쉽습니다.


11

SnakeYAML을 사용하여 응답 시작

class A
{

    public static void main(String[] a)
    {
         new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point());
    }
}

편집 : ungolfed it

그것이 어떻게 작동하는지 알아내는 것은 독자에게 달려 있습니다. : P (tip : stackoverflow.com)

그건 그렇고 : 재귀는 SnakeYAML에 의해 동적으로 이루어집니다 (직렬화 된 필드를 어떻게 감지하고 Point소스 코드 에서보고하는지 알 수 있습니다 )

편집 : 작동 방식을 알려줍니다.

SnakeYAML은 쌍을 찾는다 getXXXsetXXX대한 동일한 이름 mthod XXX게터의 타입의 파라미터 설정 부와 동일 리턴; 그리고 놀랍게도 Point클래스에는 Point getLocation()and void setLocation(Point P)가 있습니다. SnakeYAML은이를 인식하지 못하고 해당 문제와 StackOverflow에서 반복됩니다. 내부에서 그들과 함께 일하고 HashMapstackoverflow.com에 요청할 때 하나를 발견 했습니다.


10

씨#

잘못 구현 된 속성 게터

class C
{
   public int P { get { return P; } }
}

static void Main()
{
   int p = new C().P;
}

14
이모. 이것은 명백한 재귀의 전형적인 예입니다 ... (그리고 유효하지 않습니다)
Ole Albers

2
글쎄, 당신이 한 번 한 번만하고 C # getter가 생각했던 방식으로 작동하지 않는다는 것을 알면 분명합니다. 결국이 코드는 멤버 변수 선언이므로 실제 멤버 변수를 작성하면 안되는 이유는 무엇입니까?
meustrus

2
이것은 복잡한 작업 방식에 지나지 않습니다static void Main() { Main(); }
Jodrell

5
@Jodrell Main()실수로 재귀를 쓰지 않을 것 입니다. 그러나 실수로 재귀 속성을 작성한 다음 스택 오버플로로 혼동되는 것은 매우 간단합니다.
svick

1
이것은 누군가 C #을 집어들 때 유용합니다.
2rs2ts
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.