스택 제한


10

최근에 나는 다른 OS를 가진 3 개의 장치에서 스택의 한계를 테스트했으며 (제한적으로 스택이 가질 수있는 최대 레벨 수를 의미합니다) 2 ^ 16 레벨에 도달 할 때마다 나에게 오버플로 오류 및 2 ^ 16-1을 넣으면 제대로 작동합니다.

내 질문은-사실입니까? 스택에 정의에 따라 최대 한계 2 ^ 16-1이 있습니까? 아니면 OS에 따라 다릅니 까?


5
here i mean by limit the maximum number of levels that can the stack have레벨이 뭐야?
tkausl


3
어떻게 테스트하고 있습니까? 2 바이트 (dword)를 입력으로 사용하고 있습니까?
pro3carp3

6
어떤 프로그래밍 언어를 사용하고 있습니까? 고정 된 수의 이러한 날카로운 제한은 OS가 할당 한 스택 크기가 아니라 언어 별 런타임에 의해 의도적으로 제한됨을 나타냅니다. 예를 들어 python은 실제 스택 오버플로를 복구하는 것을 막기 위해 기본적으로 1000을 제한하는 것 같습니다 (실제 스택 오버플로를 복구하는 것은 어렵습니다)
CodeInChaos

답변:


20

그것은 운영 체제에 따라 다르며 (및 컴퓨터에 따라 다름) 일부 OS에서는 한계를 구성 (및 증가) 할 수있는 방법이 있습니다. 일부 컴파일러 ( 일부 제한된 종류의 C 코드에 대한 최근 GCC 포함 )가 일부 테일 호출 을 최적화 할 수 있기 때문에 컴파일러에 따라 (또는 프로그래밍 언어 구현에 따라 다름 )도 있습니다 .

(일부 프로그래밍 언어 사양 에는 꼬리 호출 최적화가 필요 합니다 (예 : R5RS ))

귀하의 질문이 합리적이라고 확신하지 못합니다 (그리고 확실히 당신의 2 16 한도는 아닙니다 ). 내 Linux 데스크톱 (Debian / Sid / x86-64, Linux 4.9 커널, 32Gb RAM, Intel i5-4690S)에서 최대 8MB 의 호출 스택 이 있을 수 있습니다. ).

멀티 스레딩ASLR 은 질문을 훨씬 더 복잡하게 만듭니다. pthread_attr_setstack (3) 참조하십시오 . 분할 스택 (종종 Go 구현에서 사용) 및 연속 전달 스타일 에 대해서도 읽으십시오 . 답변 도 참조하십시오 .

가치있는 것을 위해 다음 C99 (및 C11) 코드를 시도했습니다.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void recfun(int x, int d) {
  printf("start recfun x=%d d=%d\n", x, d);
  fflush(NULL);
  if (d>0)
    recfun(x+1, d-1);
  printf("end recfun x=%d d=%d\n", x, d);
}

int main(int argc, char**argv) {
  int md = argc>1?atoi(argv[1]):10000;
  printf ("start md=%d\n", md);
  recfun(0, md);
  printf("end md=%d clock=%ld µs\n", md, clock());
}    
// eof recur.c

그리고 recur(GCC 6으로 컴파일 된) 해당 프로그램을 ( 2 16 한도 이상 gcc -Wall -O recur.c -o recur) 실행할 수있었습니다 . 로 그것을도했다. 으로 는 (a 분쇄 된 스택 오버플 레벨 ). 다른 테스트에 대한 인내심이 없습니다. 컴퓨터에서 사용해보십시오. 최적화를 요청하는 것을 잊지 마십시오.recur 161000recur 256000recur 456000x=272057

경험에 따르면 (데스크톱, 랩톱, 태블릿의 경우) 통화 스택을 1MB 미만으로 유지하는 것이 좋습니다.

또한 통과함으로써 -fstack-usage gcc 나는 다음의지고있어 recur.su파일을 (숫자는 바이트 내 8Mb의 스택 제한 직관과 일치하며 잊지 마세요 main수행 할 때 커널에 의해 설치된 호출 프레임, 그리고 더 중요한 것은 초기 스택 레이아웃, (2에서 execve를 ) ..., crt0 ) :

 recur.c:5:10:recfun    32  static
 recur.c:13:9:main  16  static

추신. 내 Arduino에는 2KB 의 RAM 이있는 Atmega328 이 있으므로 확실히 그다지 반복 할 수 없습니다. Arduinos에서는 실제로 수백 개의 스택 프레임 만 실제로 가능하다고 생각합니다.


3

프로세스 윈도우의 메인 스레드에 대한 스택 크기는 링커에 의해 설정됩니다. 기본값은 1MB이지만 / STACK 스위치로 조정할 수 있습니다. 나중에 작성된 스레드는 CreateThread 함수의 dwStackSize 매개 변수를 사용할 수 있습니다.

따라서 다양한 Windows OS를 테스트하는 경우 NT4.0 이상부터 기본 스택 크기가 모두 동일합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.