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 ();
}