Share via


C28615

advertencia C28615: debe llamar a _resetstkoflw en el bloque __except() al llamar a _alloca en el bloque __try. No llame a _resetstkoflw desde un bloque catch()

La herramienta Análisis de código notifica esta advertencia cuando las aplicaciones llaman a la función _resetstkoflw dentro de un bloque catch, o cuando las aplicaciones llaman a alloca en el bloque try sin llamar a _resetstkoflw en el bloque except.

Un subproceso solo puede detectar una excepción de desbordamiento de pila (generada desde una llamada a _alloca) a menos que la pila se repare (por ejemplo, por _resetstkoflw) después de cada excepción. Si la pila no se corrige después de que se genere la primera excepción desde _alloca, una segunda excepción dará lugar a la finalización inmediata y silenciosa del proceso.

Debe llamar a _resetstkoflw cuando el puntero de pila actual apunte a una dirección superior a la tercera página de la pila. Esto se debe a que no tiene sentido hacer que una página de protección salga de la página actual a la que apunta el puntero de pila (o apuntará a en un momento).

No se debe llamar a la función _resetstkoflw desde una expresión de filtro de controlador de excepciones estructurada o desde una función llamada desde una expresión de filtro de controlador de excepciones estructurada.

Ejemplos

La herramienta Análisis de código notifica esta advertencia para el ejemplo siguiente porque se llama a la expresión de filtro antes de que se produzca el desenredado de la pila. Cuando hay un desbordamiento de pila, se llama a la expresión de filtro cuando el puntero de pila actual apunta a la tercera página desde la parte inferior de la pila.

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

En el ejemplo siguiente también se produce un error por motivos similares.


__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;
 }
}

En el ejemplo siguiente se evita correctamente el error.

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