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