2010-09-22 10 views
5

Estoy interesado en la parte más corta y más precisa del código C# que produzca de manera confiable una segfault, idealmente sin llamar directamente a ningún código no administrado.¿Cuál es una manera canónica de producir una falla de segmentación en C#?

+1

No es probable que suceda. Segfault en el código administrado significaría un error en el JIT/tiempo de ejecución y en algunas situaciones una vulnerabilidad. Si es posible, se solucionará pronto. – viraptor

+0

Una respuesta compilable completa a esto debería ser solo una docena de líneas. –

+0

@viraptor: No, el tiempo de ejecución puede manejar el error de segmentación (en Windows el término es "infracción de acceso") y lanzar una NullPointerException, pero eso no es lo mismo que no tener nunca un error de segmentación. Todo lo que necesita es código no verificable (en C#, eso significa compilar '/ inseguro ') –

Respuesta

7

Lo que está buscando no está nada claro, pero supongo que hasta ahora es tan bueno como cualquier respuesta, y es lo mínimo posible.

System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);

+0

Sí, gracias. Eso es lo que buscaba. – Tom

0

compilar con csc con la opción /unsafe:

class Program 
{ 
    static void Main(string[] args) 
    { 
     unsafe 
     { 
      int *p = null; 
      *p = 5; 
     } 
    } 
} 
+2

Eso en realidad arroja una NullReferenceException, que es bastante fácil de obtener con simple .NET. Supongo que OP está buscando algo más parecido a AccessViolationException. –

+0

Debajo de las cubiertas, una violación de acceso (código de excepción nativo 0xC0000005) resulta de la desreferencia del puntero nulo que luego es atrapada por el CLR y traducida a una instancia de 'System.NullReferenceException'. –

0

Como se señaló en los comentarios anteriores, no hay tal cosa como una violación de segmento en Windows, y no dijo nada acerca de mono en Linux. Así que supongo que realmente quiso decir una violación de acceso.

Aquí está una manera de conseguir uno:

unsafe { 
    int* a = (int*) -4; 
    *a = 0; 
} 

(se debe compilar con la opción /unsafe.)

Mi primer intento utilizan los botones 0 como la dirección, pero que resultó lanzar una llanura de edad NullReferenceException, que puede obtener sin un código inseguro. Pero la dirección negativa obtiene una AccessViolationException en mi cuadro Vista x64.

+0

Curiosamente, esto da como resultado 'NullReferenceException' en Mono 1.9.1 que se ejecuta en Linux, por lo que supongo que depende de la arquitectura (o Mono se equivoca!). –

+0

Gracias. En lo que respecta a la terminología, estoy contento de llamar a una "violación de acceso" un segfault, siempre lo he sido. – Tom

0

respuesta de Michael no estaba trabajando para mí, tal vez ese caso está atrapado ahora. Marshal.ReadInt32() solo me da un "SystemError: Intenté leer o escribir en la memoria protegida". con .NET 4.5 en Windows para varios valores pasados. Utilicé lo siguiente, sin embargo, segfeults para mí tanto en Windows como en mono 4.0.4.1:

using System.Runtime.InteropServices; 

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    public delegate void UNMANAGED_CALLBACK(); 

    public void Crash() 
    { 
     var crash = (UNMANAGED_CALLBACK)Marshal.GetDelegateForFunctionPointer((IntPtr) 123, typeof(UNMANAGED_CALLBACK)); 
     crash(); 
    } 
Cuestiones relacionadas