다음을 통해 공유


C28615

경고 C28615: __try 블록에서 _alloca 호출할 때 __except() 블록에서 _resetstkoflw 호출해야 합니다. catch() 블록 내부에서 _resetstkoflw 호출하지 마세요.

코드 분석 도구는 애플리케이션이 catch 블록 내에서 _resetstkoflw 함수를 호출하거나 애플리케이션이 예외 블록에서 _resetstkoflw 호출하지 않고 try 블록에서 alloca를 호출할 때 이 경고를 보고합니다.

스레드는 각 예외 후에 스택을 복구(예: _resetstkoflw)하지 않는 한 하나의 스택 오버플로 예외( _alloca 호출에서 발생)만 catch할 수 있습니다. _alloca 첫 번째 예외가 발생한 후 스택이 수정되지 않으면 두 번째 예외로 인해 즉시 자동 프로세스가 종료됩니다.

현재 스택 포인터가 스택의 세 번째 페이지보다 높은 주소를 가리키는 경우 _resetstkoflw 호출해야 합니다. 스택 포인터가 가리키는 현재 페이지에서 가드 페이지를 만드는 것은 의미가 없기 때문입니다(또는 잠시 후 가리키기).

_resetstkoflw 함수는 구조적 예외 처리기 필터 식이나 구조적 예외 처리기 필터 식에서 호출된 함수에서 호출해서는 안 됩니다.

예제

스택 해제가 발생하기 전에 필터 식이 호출되기 때문에 코드 분석 도구는 다음 예제에 대해 이 경고를 보고합니다. 스택 오버플로가 있는 경우 현재 스택 포인터가 스택 아래쪽의 세 번째 페이지를 가리키면 필터 식이 호출됩니다.

__try 
{
    /* The following could cause stack overflow */
    char *x = _alloca (i);
}
__except ((GetExceptionCode () == EXCEPTION_STACK_OVERFLOW) 
    ? (_resetstkoflw (), EXCEPTION_EXECUTE_HANDLER) 
    : EXCEPTION_CONTINUE_SEARCH)
{
}

다음 예제도 비슷한 이유로 실패합니다.


__try 
{
 char *x = _alloca (i);
}
__except (SEHFilter (GetExceptionCode ()))
{
}

int SEHFilter (DWORD dwExceptionCode)
{
 if (dwExceptionCode == EXCEPTION_STACK_OVERFLOW)
 {
 _resetstkoflw ();
 return EXCEPTION_EXECUTE_HANDLER;
 }
 else
 {
 return EXCEPTION_CONTINUE_SEARCH;
 }
}

다음 예제에서는 오류를 방지합니다.

__try
{
    char *x = _alloca (i);
}
__except ((GetExceptionCode () == EXCEPTION_STACK_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
    // In this block the stack has already been unwound,
    // so this call will succeed.
_resetstkoflw ();
}