C28615
Warnung C28615: Muss _resetstkoflw im Block __except() aufrufen, wenn _alloca im __try-Block aufgerufen wird. Rufen Sie _resetstkoflw nicht innerhalb eines catch()-Blocks auf.
Das Codeanalysetool meldet diese Warnung, wenn Anwendungen die _resetstkoflw-Funktion in einem Catch-Block aufrufen oder wenn Anwendungen alloca im Try-Block aufrufen, ohne _resetstkoflw im Außer-Block aufzurufen.
Ein Thread kann nur eine Stapelüberlaufausnahme (ausgelöst von einem Aufruf an _alloca) abfangen, es sei denn, der Stapel wird nach jeder Ausnahme repariert (z. B. durch _resetstkoflw). Wenn der Stapel nicht behoben wird, nachdem die erste Ausnahme von _alloca ausgelöst wurde, führt eine zweite Ausnahme zu einer sofortigen und unbeaufsichtigten Prozessbeendigung.
Sie müssen _resetstkoflw aufrufen, wenn der aktuelle Stapelzeiger auf eine Adresse zeigt, die höher ist als die dritte Seite des Stapels. Dies liegt daran, dass es nicht sinnvoll ist, eine Schutzseite aus der aktuellen Seite zu machen, auf die der Stapelzeiger zeigt (oder auf die der Stapelzeiger in einem Moment zeigt).
Die _resetstkoflw-Funktion sollte nicht von einem strukturierten Ausnahmehandlerfilterausdruck oder von einer Funktion aufgerufen werden, die aus einem strukturierten Ausnahmehandlerfilterausdruck aufgerufen wird.
Beispiele
Das Codeanalysetool meldet diese Warnung für das folgende Beispiel, da der Filterausdruck aufgerufen wird, bevor die Stapelentladung erfolgt. Wenn es einen Stapelüberlauf gibt, wird der Filterausdruck aufgerufen, wenn der aktuelle Stapelzeiger vom unteren Rand des Stapels auf die dritte Seite zeigt.
__try
{
/* The following could cause stack overflow */
char *x = _alloca (i);
}
__except ((GetExceptionCode () == EXCEPTION_STACK_OVERFLOW)
? (_resetstkoflw (), EXCEPTION_EXECUTE_HANDLER)
: EXCEPTION_CONTINUE_SEARCH)
{
}
Das folgende Beispiel schlägt ebenfalls aus ähnlichen Gründen fehl.
__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;
}
}
Im folgenden Beispiel wird der Fehler erfolgreich vermieden.
__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 ();
}