¿Por qué este ensamblaje modificado no se ejecuta? (El compilador JIT encontró una limitación interna).

Modifiqué el código de bytes de un ensamblaje para eliminar un error y ahora, cuando intento usarlo, aparece una excepción de programa no válido. Todo lo que he hecho es reemplazar este código con NOPS:

catch (Exception exception1)
{
    Exception exception = exception1;
    if (exception as InvalidValueException == null)
    {
        throw new InvalidGenerationException(2);
    }
    else
    {
        throw exception;
    }
}

IL antes:

catch [mscorlib]System.Exception
{
    IL_022f: stloc.s exception
    IL_0231: ldloc.s exception
    IL_0233: isinst Custom.InvalidValueException
    IL_0238: brfalse.s IL_023d

    IL_023a: ldloc.s exception
    IL_023c: throw

    IL_023d: ldc.i4.1
    IL_023e: newobj instance void Custom.InvalidGenerationException ...
    IL_0243: throw
}

IL después de:

catch [mscorlib]System.Exception
{
    IL_022f: nop
    IL_0230: nop
    IL_0231: nop
    IL_0232: nop
    IL_0233: nop
    IL_0234: nop
    IL_0235: nop
    IL_0236: nop
    IL_0237: nop
    IL_0238: nop
    IL_0239: nop
    IL_023a: nop
    IL_023b: nop
    IL_023c: nop
    IL_023d: nop
    IL_023e: nop
    IL_023f: nop
    IL_0240: nop
    IL_0241: nop
    IL_0242: nop
    IL_0243: nop
}

¿Alguna idea de por qué está mal esto?

¡Gracias!

preguntado el 22 de mayo de 12 a las 14:05

¿Qué pasa si eliminas todos los nops? -

No puedo cambiar la longitud del ensamblaje con las utilidades que tengo actualmente, y normalmente no es una buena idea (no estoy seguro si IL tiene saltos de este tipo) -

¿Por qué no puede simplemente manejar la excepción? Tragar una excepción es generalmente una mala idea. -

Porque no es mi código, es un ensamblaje de terceros con un defecto y es el propio tercero el que está manejando la excepción cuando no debería. Estoy solucionando el problema mientras espero una nueva versión de la tercera parte que seguramente llevará algún tiempo. -

Consejo profesional: utilice siempre PEVerify despues de correr ilasm. -

1 Respuestas

Su original catch el bloque siempre tirará. Es decir, no hay forma de salir del bloque "normalmente".

tu modificado catch el bloque no arroja, por lo que debe salir del bloque normalmente. Tendrás que usar leave or leave.s Para hacer eso.

(Es posible que también necesite pop la excepción capturada fuera de la pila para mantener las cosas ordenadas. Aunque no estoy seguro de eso, tendrás que probarlo y verlo por ti mismo).

catch [mscorlib]System.Exception
{
    IL_022f: pop                // not certain if pop is necessary
    IL_0230: leave.s IL_0244
    IL_0232: nop
    IL_0233: nop
    IL_0234: nop
    IL_0235: nop
    IL_0236: nop
    IL_0237: nop
    IL_0238: nop
    IL_0239: nop
    IL_023a: nop
    IL_023b: nop
    IL_023c: nop
    IL_023d: nop
    IL_023e: nop
    IL_023f: nop
    IL_0240: nop
    IL_0241: nop
    IL_0242: nop
    IL_0243: nop
}
IL_0244: ret    // or whatever

contestado el 22 de mayo de 12 a las 15:05

La instrucción de salida vacía la pila de evaluación, por lo que parece que no se necesita el pop. ¡Gracias! - Ignacio Soler García

@SoMoS: Tenía la sensación de que ese podría ser el caso, pero no estaba 100 % seguro y no tuve tiempo de comprobarlo. - LucasH

si, lo se, solo dejo el comentario para futuras referencias. Gracias de nuevo. - Ignacio Soler García

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.