C28615
aviso C28615: deve chamar _resetstkoflw no bloco __except() ao chamar _alloca no bloco __try. Não chame _resetstkoflw de dentro de um bloco catch()
A ferramenta Análise de Código relata esse aviso quando os aplicativos chamam a função _resetstkoflw dentro de um bloco catch ou quando os aplicativos chamam alloca no bloco try sem chamar _resetstkoflw no bloco exceto.
Um thread pode capturar apenas uma exceção de estouro de pilha (gerada de uma chamada para _alloca), a menos que a pilha seja reparada (por exemplo, por _resetstkoflw) após cada exceção. Se a pilha não for corrigida depois que a primeira exceção for gerada de _alloca, uma segunda exceção resultará em encerramento imediato e silencioso do processo.
Você deve chamar _resetstkoflw quando o ponteiro de pilha atual aponta para um endereço maior que a terceira página na pilha. Isso ocorre porque não faz sentido fazer uma página de proteção fora da página atual para a qual o ponteiro de pilha está apontando (ou apontará em um momento).
A função _resetstkoflw não deve ser chamada de uma expressão de filtro de manipulador de exceção estruturada ou de uma função chamada de uma expressão de filtro de manipulador de exceção estruturada.
Exemplos
A ferramenta Análise de Código relata esse aviso para o exemplo a seguir porque a expressão de filtro é chamada antes que o desenrolamento da pilha ocorra. Quando há um estouro de pilha, a expressão de filtro é chamada quando o ponteiro de pilha atual está apontando para a terceira página da parte inferior da pilha.
__try
{
/* The following could cause stack overflow */
char *x = _alloca (i);
}
__except ((GetExceptionCode () == EXCEPTION_STACK_OVERFLOW)
? (_resetstkoflw (), EXCEPTION_EXECUTE_HANDLER)
: EXCEPTION_CONTINUE_SEARCH)
{
}
O exemplo a seguir também falha por motivos semelhantes.
__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;
}
}
O exemplo a seguir evita com êxito o erro.
__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 ();
}