Necesito escribir una prueba que compruebe que mi código puede manejar una excepción AccessViolationException (o cualquier otra excepción WIN32 Corrupted State - CSE), que se produce en un contexto inseguro, por lo general llamando a un tercero . Todo esto debe hacerse usando C# en .net 4.0.Cómo probar el manejo de AccessViolationException
Encontré esta pregunta relacionada How to handle AccessViolationException y este artículo relacionado http://dotnetslackers.com/articles/net/All-about-Corrupted-State-Exceptions-in-NET4.aspx, que explica cómo atrapar estos CSE y sus antecedentes.
Así que me gustaría provocar un WIN32 CSE en una prueba, para asegurar el manejo correcto en mi aplicación. Algo así como:
Algunos clase de ejemplo para probar:
public class MyExceptionHandler
{
[HandleProcessCorruptedStateExceptions]
public void HandleCorruptedStateException()
{
try
{
//Force genuine unsafe AccessViolationException
//not just a throw new AccessViolationException
}
catch(Exception e)
{
//Log/cleanup/other
}
}
public void DoesNotHandleCorruptedStateException()
{
try
{
//Force genuine unsafe AccessViolationException
//not just a throw new AccessViolationException
}
catch (Exception e)
{
//Log/cleanup/other
}
}
}
una prueba:
class MyTest
{
[Test]
public void ShouldVerifyThatAnAccessViolationExceptionIsHandledCorrectly()
{
var handler = new MyExceptionHandler();
Assert.DoesNotThrow(() => handler.HandleCorruptedStateException());
}
[Test]
public void ShouldVerifyThatAnAccessViolationExceptionIsNotHandledCorrectly()
{
var handler = new MyExceptionHandler();
Assert.Throws<AccessViolationException>(() => handler.DoesNotHandleCorruptedStateException());
}
}
¿Alguien tiene una sugerencia de cómo achive esto sin mucho trabajo (por ejemplo, escribiendo un inseguro. lib que causa esta excepción).
Saludos cordiales
Actualizado: Para que coincida con mi solución final, gracias a JaredPar.
public class MyExceptionHandler
{
[HandleProcessCorruptedStateExceptions]
public void HandleCorruptedStateException()
{
try
{
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
catch(Exception e)
{
//Log/cleanup/other
}
}
public void DoesNotHandleCorruptedStateException()
{
try
{
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
catch (Exception e)
{
//Log/cleanup/other
}
}
}
TIP: Para comprobar esto, utilice manualmente una aplicación de consola sencilla, desde la línea de comandos:
class Program
{
static void Main(string[] args)
{
var handler = new MyExceptionHandler();
if (args.Length > 1)
{
handler.HandleCorruptedStateException();
}
else
{
handler.DoesNotHandleCorruptedStateException();
}
}
}
Gracias, pero esto no genera un CSE, solo una ArgumentNullException. Tiene que ser un WinEdge Win32 genuino que hará que la aplicación se bloquee si no se maneja en try catch + se marca con el atributo [HandleProcessCorruptedStateExceptions], etc. como se describe en el artículo. –
Soy corregido. Esto SÍ funciona :-D. Hice un error en mi prueba (típico). Muchas gracias :) –