Partager via


C28615

avertissement C28615 : Doit appeler _resetstkoflw dans le bloc __except() lors de l’appel de _alloca dans le bloc __try. N’appelez pas _resetstkoflw à partir d’un bloc catch()

L’outil Analyse du code signale cet avertissement lorsque des applications appellent la fonction _resetstkoflw dans un bloc catch, ou lorsque des applications appellent alloca dans le bloc try sans appeler _resetstkoflw dans le bloc except.

Un thread ne peut intercepter qu’une seule exception de dépassement de capacité de la pile (déclenchée à partir d’un appel à _alloca), sauf si la pile est réparée (par exemple, par _resetstkoflw) après chaque exception. Si la pile n’est pas corrigée après le déclenchement de la première exception à partir de _alloca, une deuxième exception entraîne l’arrêt immédiat et silencieux du processus.

Vous devez appeler _resetstkoflw lorsque le pointeur de la pile actuelle pointe vers une adresse supérieure à la troisième page de la pile. Cela est dû au fait qu’il n’est pas judicieux de créer une page de garde à partir de la page active vers laquelle le pointeur de pile pointe (ou vers laquelle il pointera dans un instant).

La fonction _resetstkoflw ne doit pas être appelée à partir d’une expression de filtre de gestionnaire d’exceptions structurée ou d’une fonction appelée à partir d’une expression de filtre de gestionnaire d’exceptions structurée.

Exemples

L’outil Analyse du code signale cet avertissement pour l’exemple suivant, car l’expression de filtre est appelée avant le déroulement de la pile. En cas de dépassement de capacité de la pile, l’expression de filtre est appelée lorsque le pointeur de pile actuel pointe vers la troisième page du bas de la pile.

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

L’exemple suivant échoue également pour des raisons similaires.


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

L’exemple suivant permet d’éviter l’erreur.

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