Compartir a través de


_resetstkoflw

Recupera de desbordamiento de pila.

Nota importanteImportante

Esta API no se puede utilizar en las aplicaciones que se ejecutan en tiempo de ejecución de Windows.Para obtener más información, vea Funciones CRT no compatibles con /ZW.

int _resetstkoflw ( void );

Valor devuelto

Distinto de cero si la función tiene éxito, cero si se produce un error.

Comentarios

La función _resetstkoflw se recupera de una condición del desbordamiento de pila, lo que permite que el continúe en lugar de generar un error de excepción grave.Si la función de _resetstkoflw no se denomina, no hay ninguna página de protección después de la excepción anterior.La próxima vez que haya un desbordamiento de pila, no habrá ninguna excepción en absoluto y el proceso finalizará sin avisar.

Si un subproceso en una aplicación provoca una excepción EXCEPTION_STACK_OVERFLOW, el subproceso ha dejado la pila en estado dañado.Esto contrasta con otras excepciones como EXCEPTION_ACCESS_VIOLATION o EXCEPTION_INT_DIVIDE_BY_ZERO, donde la pila no está dañado.La pila se establece en un valor más pequeño cuando el programa primero se carga.La pila a crece a petición para satisfacer las necesidades del subproceso.Esto se implementa mediante una página con acceso de PAGE_GUARD al final de la pila actual.Para obtener más información, vea Crear páginas de restricción.

Cuando el código hace que el puntero de pila elija una dirección en esta página, se produce una excepción y el sistema a las tres cosas siguientes:

  • Quite la protección de PAGE_GUARD en la restricción de modo que el subproceso pueda leer y escribir datos en la memoria.

  • Asigna una nueva página de restricción que se busque una página en la última.

  • Ejecute la instrucción que produjo la excepción.

De esta manera, el sistema puede aumentar el tamaño de la pila del subproceso automáticamente.Cada subproceso de un proceso tiene un tamaño de pila máximo.El tamaño de pila se establece en tiempo de compilación por /STACK (Asignaciones de la pila), o por la instrucción de STACKSIZE en el archivo .def para el proyecto.

Cuando se supera este tamaño de pila máximo, el sistema hace las tres cosas siguientes:

  • Quite la protección de PAGE_GUARD en la página de restricción, como se ha descrito anteriormente.

  • Intenta asignar una nueva página de restricción en la última.Sin embargo, se produce un error porque se ha superado el tamaño de pila máximo.

  • Produce una excepción de modo que el subproceso pueda controlarla en el bloque de excepción.

Observe que, en este punto, la pila ya no tiene una página de la restricción.La próxima vez que el programa aumenta la pila hasta el final, donde debe haber una página de la restricción, las etiquetas de programa más allá del final de la pila y hace una infracción de acceso.

Llame a _resetstkoflw para restaurar la restricción siempre que la recuperación se haga después de una excepción de desbordamiento de pila.Esta función se puede llamar desde dentro del cuerpo principal de __except bloqueado o fuera del bloque __except .Sin embargo, hay algunas restricciones en cuando se debe utilizar._resetstkoflw nunca debe llamar de:

  • Una expresión de filtro.

  • Una función de filtro.

  • Una función denominada de una función de filtro.

  • Un bloque catch.

  • Un bloque de __finally.

En estos puntos, el montón no se desenreda todavía suficientemente.

Se generan las excepciones de desbordamiento de pila como excepciones estructuradas, no excepciones de C++, por lo que _resetstkoflw no son útiles en catch ordinario bloquea porque no detecta una excepción de desbordamiento de pila.Sin embargo, si _set_se_translator se utilizan para implementar un traductor estructurado de excepciones que produzca excepciones de C++ (como en el segundo ejemplo), una excepción de desbordamiento de pila da lugar a la excepción de c++. que pueden controlarse mediante el bloque catch de c++.

No es seguro llamar a _resetstkoflw en el bloque catch de c++. que se alcanza de una excepción producida por la función estructurada del traductor de la excepción.En este caso, el espacio de pila no se libera y el puntero de pila no se restaura hasta fuera del bloque catch, aunque los destructores se han llamado para cualquier objeto destructible antes del bloque catch.Esta función no se debería llamar a hasta que se libere el espacio de pila y se ha restablecido el puntero de pila.Por consiguiente, debe llamar sólo después de salir del bloque catch.Mientras poco espacio de pila posible se debe utilizar en el bloque catch porque un desbordamiento de pila que aparece en el bloque catch que sí mismo intenta recuperar de un desbordamiento de pila anterior no es recuperable y puede hacer que el programa deje de responder mientras el desbordamiento en el bloque catch desencadena una excepción que sí mismo es administrado por el mismo bloque catch.

Hay situaciones don _resetstkoflw puede producirse aunque se utiliza en una ubicación adecuada, como en un bloque __except .Si, incluso después de desenredo de la pila, no hay suficiente espacio de pila salido para ejecutar _resetstkoflw sin escribir en la última página del montón, _resetstkoflw no puede restaurar la última página del montón como página de restricción y devuelve 0, que indica el error.Por consiguiente, el uso seguro de esta función debe incluir comprobar el valor devuelto en lugar de suponer que la pila es seguro utilizar.

El control estructurado de excepciones no detecta una excepción de STATUS_STACK_OVERFLOW cuando la aplicación se compila con /clr o /clr:pure (vea /clr (Compilación de Common Language Runtime)).

Requisitos

Rutina

Encabezado necesario

_resetstkoflw

<malloc.h>

Para obtener más información de compatibilidad, vea Compatibilidad en la Introducción.

Versiones de Bibliotecas: desde Características de la biblioteca CRT.

Ejemplo

El ejemplo siguiente se muestra el uso recomendado de la función de _resetstkoflw.

// crt_resetstkoflw.c
// Launch program with and without arguments to observe
// the difference made by calling _resetstkoflw.

#include <malloc.h>
#include <stdio.h>
#include <windows.h>

void recursive(int recurse)
{
   _alloca(2000);
   if (recurse)
      recursive(recurse);
}

// Filter for the stack overflow exception.
// This function traps the stack overflow exception, but passes
// all other exceptions through. 
int stack_overflow_exception_filter(int exception_code)
{
   if (exception_code == EXCEPTION_STACK_OVERFLOW)
   {
       // Do not call _resetstkoflw here, because
       // at this point, the stack is not yet unwound.
       // Instead, signal that the handler (the __except block)
       // is to be executed.
       return EXCEPTION_EXECUTE_HANDLER;
   }
   else
       return EXCEPTION_CONTINUE_SEARCH;
}

int main(int ac)
{
   int i = 0;
   int recurse = 1, result = 0;

   for (i = 0 ; i < 10 ; i++)
   {
      printf("loop #%d\n", i + 1);
      __try
      {
         recursive(recurse);

      }

      __except(stack_overflow_exception_filter(GetExceptionCode()))
      {
         // Here, it is safe to reset the stack.

         if (ac >= 2)
         {
            puts("resetting stack overflow");
            result = _resetstkoflw();
         }
      }

      // Terminate if _resetstkoflw failed (returned 0)
      if (!result)
         return 3;
   }

   return 0;
}

Resultados del ejemplo

Sin argumentos program:

loop #1

El programa deja de responder sin ejecutar otras iteraciones.

Con los argumentos de programa:

loop #1
resetting stack overflow
loop #2
resetting stack overflow
loop #3
resetting stack overflow
loop #4
resetting stack overflow
loop #5
resetting stack overflow
loop #6
resetting stack overflow
loop #7
resetting stack overflow
loop #8
resetting stack overflow
loop #9
resetting stack overflow
loop #10
resetting stack overflow

89f73td2.collapse_all(es-es,VS.110).gifDescripción

El ejemplo siguiente se muestra el uso recomendado de _resetstkoflw en un programa donde las excepciones estructuradas se convierten en excepciones de C++.

89f73td2.collapse_all(es-es,VS.110).gifCódigo

// crt_resetstkoflw2.cpp
// compile with: /EHa
// _set_se_translator requires the use of /EHa
#include <malloc.h>
#include <stdio.h>
#include <windows.h>
#include <eh.h>

class Exception { };

class StackOverflowException : Exception { };

// Because the overflow is deliberate, disable the warning that
// this function will cause a stack overflow.
#pragma warning (disable: 4717)
void CauseStackOverflow (int i)
{
        // Overflow the stack by allocating a large stack-based array
        // in a recursive function.
        int a[10000];
        printf("%d ", i);
        CauseStackOverflow (i + 1);
}

void __cdecl SEHTranslator (unsigned int code, _EXCEPTION_POINTERS*)
{
   // For stack overflow exceptions, throw our own C++ 
   // exception object.
   // For all other exceptions, throw a generic exception object.
   // Use minimal stack space in this function.
   // Do not call _resetstkoflw in this function.

   if (code == EXCEPTION_STACK_OVERFLOW)
      throw StackOverflowException ( );
   else
      throw Exception( );
}

int main ( )
{
        bool stack_reset = false;
        bool result = false;

        // Set up a function to handle all structured exceptions,
        // including stack overflow exceptions.
        _set_se_translator (SEHTranslator);

        try
        {
            CauseStackOverflow (0);
        }
        catch (StackOverflowException except)
        {
                // Use minimal stack space here.
                // Do not call _resetstkoflw here.
                printf("\nStack overflow!\n");
                stack_reset = true;
        }
        catch (Exception except)
        {
                // Do not call _resetstkoflw here.
                printf("\nUnknown Exception!\n");
        }
        if (stack_reset)
        {
          result = _resetstkoflw();
          // If stack reset failed, terminate the application.
          if (result == 0)
             exit(1);
        }

        void* pv = _alloca(100000);
        printf("Recovered from stack overflow and allocated 100,000 bytes"
               " using _alloca.");

   return 0;
}

Resultados del ejemplo

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Stack overflow!
Recovered from stack overflow and allocated 100,000 bytes using _alloca.

Equivalente en .NET Framework

No es aplicable Para llamar a la función estándar de C, utilice PInvoke. Para obtener más información, vea La invocación de plataforma ejemplos.

Vea también

Referencia

_alloca