C28615

警告 C28615:调用 __try 块中的_alloca时,必须调用 __except () 块中的_resetstkoflw。 不要从 catch () 块内部调用_resetstkoflw

当应用程序调用 catch 块中的 _resetstkoflw 函数,或者应用程序调用 try 块中的 alloca 而不调用 except 块中的 _resetstkoflw 时,代码分析工具将报告此警告。

线程只能捕获从调用_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 ();
}