다음을 통해 공유


_resetstkoflw

스택 오버플로 복구합니다.

중요중요

이 API는 Windows 런타임에서 실행 되는 응용 프로그램에서 사용할 수 없습니다.자세한 내용은 /zw에 지원 되는 CRT 함수.

int _resetstkoflw ( void );

반환 값

함수가 성공 하면 0을 실패할 경우 0이 아닌.

설명

_resetstkoflw 함수는 스택 오버플로 상태를 복구하여 프로그램이 치명적 예외 오류와 함께 실패하는 대신 계속 실행되도록 합니다.경우는 _resetstkoflw 함수를 호출할 경우, 앞의 예외 다음 가드 페이지가 없습니다.다음에 스택 오버플로가 발생하면 예외가 전혀 발생하지 않고 프로세스가 경고 없이 종료됩니다.

스레드 응용 프로그램에서 발생 하는 경우는 EXCEPTION_STACK_OVERFLOW 예외 스레드가 있는 왼쪽 스택 손상 된 상태에 있습니다.달리 다른 예외 등이 EXCEPTION_ACCESS_VIOLATION 또는 EXCEPTION_INT_DIVIDE_BY_ZERO, 스택 손상 되지 않은 것입니다.프로그램이 처음 로드 될 때 스택을 임의로 작은 값으로 설정 됩니다.스택 다음 스레드가 요구를 충족 시를 증가 합니다.이 PAGE_GUARD 액세스 된 페이지는 현재 스택의 끝에 배치 하 여 구현 됩니다.자세한 내용은 가드 페이지 만들기.

이 페이지의 주소를 가리키도록 스택 포인터의 코드를 발생 하는 경우 예외가 발생 하 고 다음 세 가지 시스템 하지:

  • 스레드 읽기 데이터를 메모리에 쓸 수 있도록 가드 페이지 PAGE_GUARD 보호를 제거 합니다.

  • 새 가드 할당 페이지에서 있는 한 페이지 맨 마지막 아래입니다.

  • 예외를 발생 시킨 명령을 다시 실행 합니다.

이 이렇게 하면 시스템 스레드에 대 한 스택 크기를 자동으로 늘릴 수 있습니다.각 스레드는 프로세스의 최대 스택 크기가 있습니다.컴파일 타임에서 스택 크기를 설정의 /STACK(스택 할당), 또는 STACKSIZE 프로젝트에 대 한.def 파일에 문.

이 최대 스택 크기를 초과 하면 시스템이 다음 세 가지 작업을 수행 합니다.

  • 가드 페이지에서 앞에서 설명한 대로 PAGE_GUARD 보호를 제거 합니다.

  • 마지막 아래 새 가드 페이지를 할당 하려고 시도 합니다.그러나 최대 스택 크기를 초과 하기 때문에 실패 합니다.

  • 스레드는 예외 블록에서 처리할 수 있도록 예외를 발생 시킵니다.

이때 스택의 가드 페이지 되어 이상, note입니다.프로그램 스택을 끝에 증가 다음 번 가드 페이지 있어야 하는 부분이 프로그램 스택의 끝을 지 나 쓰고 액세스 위반이 발생 합니다.

호출 _resetstkoflw 때 스택 오버플로 예외 후 복구를 수행할 때마다 가드 페이지를 복원할 수 있습니다.본문 안에이 함수를 호출할 수 있습니다에서 __except 블록 또는 외부는 __except 블록.사용할 때 몇 가지 제한이 있습니다._resetstkoflw절대로에서 호출 해야 합니다.

  • 필터 식입니다.

  • 필터 함수입니다.

  • 필터 함수에서 호출 하는 함수입니다.

  • A catch 블록.

  • A __finally block.

이러한 시점에서 스택 아직 충분히 해제할 수 없습니다.

스택 오버플로 예외 생성 구조적된 예외로, c + + 예외 등 _resetstkoflw 에서 일반적인 유용 catch 차단할 때 스택 오버플로 예외는 catch 하지 않습니다.그러나 경우 _set_se_translator 입니다 (예를 들어 두 번째) c + + 예외를 throw 하는 구조적된 예외 변환기를 구현 하는 데 사용, 스택 오버플로 예외는 c + + catch 블록에서 처리할 수 있는 c + + 예외 결과입니다.

안전 하지 않은 _resetstkoflw c + + catch 블록에서 구조적된 예외 변환기 함수에서 throw 되는 예외에 도달 합니다.이 경우 스택 공간이 해제 되지 않습니다 및 catch 블록 외부도 소멸자 모든 catch 블록 전에 대량으로 파괴할 수 개체에 대해 호출 되지 않은 때까지 스택 포인터를 다시 설정 되지 않습니다.스택 공간이 확보 되 고 스택 포인터를 다시 설정 될 때까지이 함수 호출할 수 없습니다.따라서 catch 블록을 끝낸 후에 호출 해야 합니다.서 자체에서 스택 오버플로 이전 복구 하려고 catch 블록에서 발생 하는 스택 오버플로 복구할 수 없기 때문에 가능한 catch 블록에 사용 해야 하 고 원인 예외 그 자체가 catch 블록에 오버플로 트리거하는 응답을 중지 하는 프로그램을 처리 하는 catch 블록 수 있습니다 스택 공간이.

경우가 위치 _resetstkoflw 내의 올바른 위치에 같이 사용 하는 경우에 실패할 수는 __except 블록.스택 해제 후도, 없는 경우, 계속 실행 하도록 충분 한 스택 공간 왼쪽 _resetstkoflw 는 스택의 마지막 페이지를 작성 하지 않고 _resetstkoflw 맨 마지막 페이지는 가드 페이지 및 실패를 나타내는 0 반환 합니다로 다시 설정 되지 않습니다.따라서 안전한 사용이 함수의 스택 사용 하기에 안전한 것을 가정 하는 반환 값 대신 검사 포함 되어야 합니다.

구조적된 예외 처리를 catch 됩니다는 STATUS_STACK_OVERFLOW 응용 프로그램을 컴파일한 경우 예외 /clr 또는 /clr:pure (참조 /clr(공용 언어 런타임 컴파일)).

요구 사항

루틴

필수 헤더

_resetstkoflw

<malloc.h>

자세한 호환성에 대 한 내용은 호환성 소개에서 합니다.

라이브러리: 의 모든 버전은 CRT 라이브러리 기능.

예제

권장 되는 사용 하는 다음 예제에서 _resetstkoflw 함수입니다.

// crt_resetstkoflw.c
// Launch program with and without arguments to observe
// the difference made by calling _resetstkoflw.

#include <malloc.h>
#include <stdio.h>
#include <windows.h>

void recursive(int recurse)
{
   _alloca(2000);
   if (recurse)
      recursive(recurse);
}

// Filter for the stack overflow exception.
// This function traps the stack overflow exception, but passes
// all other exceptions through. 
int stack_overflow_exception_filter(int exception_code)
{
   if (exception_code == EXCEPTION_STACK_OVERFLOW)
   {
       // Do not call _resetstkoflw here, because
       // at this point, the stack is not yet unwound.
       // Instead, signal that the handler (the __except block)
       // is to be executed.
       return EXCEPTION_EXECUTE_HANDLER;
   }
   else
       return EXCEPTION_CONTINUE_SEARCH;
}

int main(int ac)
{
   int i = 0;
   int recurse = 1, result = 0;

   for (i = 0 ; i < 10 ; i++)
   {
      printf("loop #%d\n", i + 1);
      __try
      {
         recursive(recurse);

      }

      __except(stack_overflow_exception_filter(GetExceptionCode()))
      {
         // Here, it is safe to reset the stack.

         if (ac >= 2)
         {
            puts("resetting stack overflow");
            result = _resetstkoflw();
         }
      }

      // Terminate if _resetstkoflw failed (returned 0)
      if (!result)
         return 3;
   }

   return 0;
}

샘플 출력

인수 없이 프로그램:

loop #1

프로그램 반복을 계속 실행 하지 않고 응답을 중지 합니다.

프로그램 인수를 사용 합니다.

loop #1
resetting stack overflow
loop #2
resetting stack overflow
loop #3
resetting stack overflow
loop #4
resetting stack overflow
loop #5
resetting stack overflow
loop #6
resetting stack overflow
loop #7
resetting stack overflow
loop #8
resetting stack overflow
loop #9
resetting stack overflow
loop #10
resetting stack overflow

89f73td2.collapse_all(ko-kr,VS.110).gif설명

다음 예제에서는 권장 되는 _resetstkoflw 프로그램 구조화 된 예외에 대 한 c + + 예외 변환 됩니다.

89f73td2.collapse_all(ko-kr,VS.110).gif코드

// crt_resetstkoflw2.cpp
// compile with: /EHa
// _set_se_translator requires the use of /EHa
#include <malloc.h>
#include <stdio.h>
#include <windows.h>
#include <eh.h>

class Exception { };

class StackOverflowException : Exception { };

// Because the overflow is deliberate, disable the warning that
// this function will cause a stack overflow.
#pragma warning (disable: 4717)
void CauseStackOverflow (int i)
{
        // Overflow the stack by allocating a large stack-based array
        // in a recursive function.
        int a[10000];
        printf("%d ", i);
        CauseStackOverflow (i + 1);
}

void __cdecl SEHTranslator (unsigned int code, _EXCEPTION_POINTERS*)
{
   // For stack overflow exceptions, throw our own C++ 
   // exception object.
   // For all other exceptions, throw a generic exception object.
   // Use minimal stack space in this function.
   // Do not call _resetstkoflw in this function.

   if (code == EXCEPTION_STACK_OVERFLOW)
      throw StackOverflowException ( );
   else
      throw Exception( );
}

int main ( )
{
        bool stack_reset = false;
        bool result = false;

        // Set up a function to handle all structured exceptions,
        // including stack overflow exceptions.
        _set_se_translator (SEHTranslator);

        try
        {
            CauseStackOverflow (0);
        }
        catch (StackOverflowException except)
        {
                // Use minimal stack space here.
                // Do not call _resetstkoflw here.
                printf("\nStack overflow!\n");
                stack_reset = true;
        }
        catch (Exception except)
        {
                // Do not call _resetstkoflw here.
                printf("\nUnknown Exception!\n");
        }
        if (stack_reset)
        {
          result = _resetstkoflw();
          // If stack reset failed, terminate the application.
          if (result == 0)
             exit(1);
        }

        void* pv = _alloca(100000);
        printf("Recovered from stack overflow and allocated 100,000 bytes"
               " using _alloca.");

   return 0;
}

샘플 출력

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Stack overflow!
Recovered from stack overflow and allocated 100,000 bytes using _alloca.

해당 .NET Framework 항목

해당 사항 없음. 표준 C 함수를 호출 하려면 PInvoke. 자세한 내용은 플랫폼 호출 예제.

참고 항목

참조

_alloca