Condividi tramite


C28615

avviso C28615: deve chiamare _resetstkoflw nel blocco __except() quando si chiama _alloca nel blocco __try. Non chiamare _resetstkoflw dall'interno di un blocco catch()

Lo strumento Analisi codice segnala questo avviso quando le applicazioni chiamano la funzione _resetstkoflw all'interno di un blocco catch o quando le applicazioni chiamano alloca nel blocco di prova senza chiamare _resetstkoflw nel blocco tranne.

Un thread può rilevare un'unica eccezione di overflow dello stack (generata da una chiamata a _alloca) a meno che lo stack non venga ripristinato (ad esempio, per _resetstkoflw) dopo ogni eccezione. Se lo stack non viene risolto dopo che la prima eccezione viene generata da _alloca, una seconda eccezione comporterà la terminazione immediata e automatica del processo.

È necessario chiamare _resetstkoflw quando il puntatore dello stack corrente punta in un indirizzo superiore alla terza pagina nello stack. Ciò è dovuto al fatto che non ha senso rendere una pagina di protezione fuori dalla pagina corrente a cui punta il puntatore dello stack (o punta a un momento).

La funzione _resetstkoflw non deve essere chiamata da un'espressione di filtro del gestore eccezioni strutturata o da una funzione chiamata da un'espressione di filtro dell'eccezione strutturata.

Esempi:

Lo strumento Analisi del codice segnala questo avviso per l'esempio seguente perché l'espressione di filtro viene chiamata prima che si verifichi l'eliminazione dello stack. Quando è presente un overflow dello stack, l'espressione di filtro viene chiamata quando il puntatore dello stack corrente punta alla terza pagina dalla parte inferiore dello stack.

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

L'esempio seguente ha esito negativo anche per motivi simili.


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

Nell'esempio seguente viene evitato correttamente l'errore.

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