Поделиться через


C28615

предупреждение C28615: должен вызывать _resetstkoflw в блоке __except() при вызове _alloca в блоке __try. Не вызывайте _resetstkoflw из блока catch()

Средство анализа кода выводит это предупреждение, когда приложения вызывают функцию _resetstkoflw в блоке catch или когда приложения вызывают alloca в блоке try без вызова _resetstkoflw в блоке except.

Поток может перехватывать только одно исключение переполнения стека (вызванное вызовом _alloca), если после каждого исключения стек не восстанавливается (например, путем _resetstkoflw). Если стек не исправлен после того, как первое исключение возникает из _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 ();
}