La familia de sistemas operativos Microsoft Windows emplea algunos mecanismos de manejo de excepciones que se basan en las especificaciones del sistema operativo .
Manejo estructurado de excepciones
El manejo de excepciones estructurado de Microsoft es el mecanismo de manejo de excepciones nativo para Windows y una tecnología precursora del manejo de excepciones vectorizado (VEH). [1] Presenta el finally
mecanismo que no está presente en las excepciones estándar de C ++ (pero está presente en la mayoría de los lenguajes imperativos introducidos más adelante). SEH se configura y gestiona por separado para cada hilo de ejecución .
Uso
Microsoft admite SEH como técnica de programación solo a nivel de compilador. MS Visual C ++ compilador cuenta con tres palabras clave: no estándar __try
, __except
y __finally
- para este propósito. Otros aspectos del manejo de excepciones están respaldados por una serie de funciones de la API de Win32 , [2] por ejemplo, RaiseException
para generar excepciones SEH manualmente.
Implementación
IA-32
Cada subproceso de ejecución en la edición de Windows IA-32 o la capa de emulación WoW64 para la versión x86-64 tiene un enlace a una lista _EXCEPTION_REGISTRATION_RECORD no documentada al comienzo de su Bloque de información de subprocesos . La __try
declaración pide esencialmente un compilador definida por EH_prolog
la función. Esa función asigna un _EXCEPTION_REGISTRATION_RECORD en la pila que apunta a la función __except_handler3
[a] en msvcrt.dll
, [b] luego agrega el registro al encabezado de la lista. Al final del __try
bloqueEH_epilog
, se llama a una función definida por el compilador que realiza la operación inversa. Cualquiera de estas rutinas definidas por el compilador puede estar en línea . Todo el definido por el programador __except
y __finally
los bloques son llamados desde dentro __except_handler3
. Si los bloques definidos por el programador están presentes, el _EXCEPTION_REGISTRATION_RECORD creado por EH_prolog
se amplía con algunos campos adicionales utilizados por __except_handler3
. [3]
En el caso de una excepción en el código de modo de usuario , el sistema operativo [c] analiza la lista _EXCEPTION_REGISTRATION_RECORD del subproceso y llama a cada manejador de excepciones en secuencia hasta que un manejador indica que ha manejado la excepción (por valor de retorno ) o la lista está agotada. El último de la lista es siempre el kernel32!UnhandledExceptionFilter
que muestra el mensaje de error de falla de protección general . [d] Luego, la lista se recorre una vez más, dando a los manejadores la oportunidad de limpiar los recursos utilizados. Finalmente, la ejecución regresa al modo kernel [e] donde el proceso se reanuda o termina.
La patente de este modo de SEH, US5628016, expiró en 2014.
x86-64
SEH en Windows de 64 bits no incluye una lista de manejadores de excepciones en tiempo de ejecución; en su lugar, utiliza una tabla de desenrollado de pila ( UNWIND_INFO
) interpretada por el sistema cuando ocurre una excepción. [4] [5] Esto significa que el compilador no tiene que generar código adicional para desenrollar la pila y llamar a los manejadores de excepciones de manera apropiada. Simplemente tiene que emitir información en forma de tablas de desenrollado sobre el diseño del marco de pila y los manejadores de excepciones especificados.
Apoyo
GCC 4.8+ de Mingw-w64 admite el uso de SEH de 64 bits para excepciones de C ++. LLVM clang es compatible __try
con x86 y x64. [6]
Manejo de excepciones vectoriales
El manejo de excepciones vectorizado se introdujo en Windows XP . [7] El manejo de excepciones vectoriales está disponible para los programadores de Windows que utilizan lenguajes como C ++ y Visual Basic . VEH no reemplaza el Manejo de excepciones estructurado (SEH), sino que VEH y SEH coexisten, y los manejadores VEH tienen prioridad sobre los manejadores SEH. [1] [7] Comparado con SEH, VEH funciona más como señales Unix entregadas por el kernel . [8]
Notas
- ^ El nombre varía en diferentes versiones de VC runtime
- ^
ntdll.dll
ykernel32.dll
, al igual que otros programas vinculados estáticamente con el tiempo de ejecución de VC, tienen esta función compilada en su lugar - ^ Más específicamente, la
ntdll!RtlDispatchException
rutina del sistema llamada desde lantdll!KiUserExceptionDispatcher
que a su vez se llama desde lant!KiDispatchException
función del núcleo. (Véase Ken Johnson (16 de noviembre de 2007). "Un catálogo de devoluciones de llamada de modo de kernel NTDLL a modo de usuario, parte 2: KiUserExceptionDispatcher" . para detalles) - ^ El mensaje se puede silenciar modificando el modo de error del proceso; el último controlador predeterminado se puede reemplazar con laAPI SetUnhandledExceptionFilter
- ^
ntdll!KiUserExceptionDispatcher
llamant!ZwContinue
ont!ZwRaiseException
Referencias
- ^ a b "Manejo de excepciones vectorizadas en Windows Server 2003 (a través de Internet Archive)" . Archivado desde el original el 18 de enero de 2008.
- ^ Microsoft Corp. (12 de noviembre de 2009). "Funciones estructuradas de manejo de excepciones" . Biblioteca de MSDN . Consultado el 17 de noviembre de 2009 .
- ^ Peter Kleissner (14 de febrero de 2009). "Manejo de excepciones de Windows - Peter Kleissner" . Archivado desde el original el 14 de octubre de 2013 . Consultado el 21 de noviembre de 2009 ., Sección de manejo de excepciones estructurado basado en compilador
- ^ "Comportamiento excepcional - Manejo de excepciones estructurado x64" . El NT Insider.
- ^ "Manejo de excepciones x64" . Documentación de VC ++ 2019 .
- ^ "Compatibilidad con MSVC" . Documentación de Clang 11 .
- ^ a b "Bajo el capó: nuevo manejo de excepciones vectorizado en Windows XP" . Archivado desde el original el 15 de septiembre de 2008.
- ^ "Windows Server 2003 descubre la información del sistema mejorada, nuevo kernel, depuración, seguridad y API de interfaz de usuario" . Archivado desde el original el 5 de mayo de 2008.
enlaces externos
- Microsoft Corp. (12 de noviembre de 2009). "Manejo estructurado de excepciones" . Biblioteca de MSDN . Consultado el 17 de noviembre de 2009 .
- Matt Pietrek (enero de 1997). "Un curso intensivo sobre las profundidades del manejo de excepciones estructuradas de Win32" . MSJ . 12 (1).Tenga en cuenta que los ejemplos que se dan allí no funcionan tal cual en los sistemas Windows modernos (posteriores a XP SP2) debido a los cambios que Microsoft realizó para abordar los problemas de seguridad presentes en el diseño inicial de SEH. Los ejemplos aún funcionan en versiones posteriores de Windows si se compilan con
/link /safeseh:no
. - "win32: manejo de excepciones estructurado seguro" . Manual de Yasm .
- Patente de EE. UU. 7,480,919 - Excepciones seguras
- Johannes Passing (20 de mayo de 2008). "Diversión con SEH de bajo nivel" . Cubre los detalles oscuros necesarios para que el código SEH de bajo nivel (y particularmente SafeSEH) funcione en Windows más moderno.
- Igor Skochinsky (6 de marzo de 2006). "Revertir Microsoft Visual C ++ Parte I: Manejo de excepciones" . OpenRCE . Consultado el 17 de noviembre de 2009 .
- Matt Miller (2 de febrero de 2009). "Prevención de la explotación del manejador de excepciones estructurado (SEH) sobrescribe con SEHOP" . Technet.
- Stéfan Le Berre, Damien Cauquil (22 de diciembre de 2009). "Omitiendo SEHOP" (PDF) . Sysdream. Archivado desde el original (PDF) el 7 de septiembre de 2012.
- Joshua J. Drake (10 de enero de 2012). "Lo antiguo se encuentra con lo nuevo: incompatibilidad de Microsoft Windows SafeSEH" . Un artículo que explica por qué Windows 7 SP1 ignora SafeSEH para algunos archivos binarios más antiguos, mientras que Windows XP SP3 lo respeta.