[Mono-list] patch for mono/jit/exception.c
Linus Upson
linus@linus.com
Sat, 4 May 2002 14:08:35 -0700
This is a multi-part message in MIME format.
------=_NextPart_000_000C_01C1F375.2E9870B0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Running NUnitConsole_mono.exe in mono on Windows exposed the following
bug:
If an exception were throw by the instruction immediately preceding a
try block, the exception would be considered to be thrown inside the try
block.
A patch is attached which appears to solve the problem. The patch won't
work if arch_handle_exception() can be called with ctx->SC_EIP pointing
to the instruction which threw the exception. I think an exception can
only be thrown by a CALL (as far as managed code is concerned) so EIP
will always point to the instruction after the CALL. If this isn't the
case, a different fix will be needed.
I believe the same problem exists on Linux as well, but I haven't
tested.
Cheers,
Linus
------=_NextPart_000_000C_01C1F375.2E9870B0
Content-Type: application/octet-stream;
name="exception.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="exception.patch"
Index: mono/jit/exception.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mono/mono/jit/exception.c,v=0A=
retrieving revision 1.6=0A=
diff -u -r1.6 exception.c=0A=
--- mono/jit/exception.c 30 Apr 2002 02:09:11 -0000 1.6=0A=
+++ mono/jit/exception.c 4 May 2002 20:43:02 -0000=0A=
@@ -171,7 +171,20 @@=0A=
for (i =3D 0; i < ji->num_clauses; i++) {=0A=
MonoJitExceptionInfo *ei =3D &ji->clauses [i];=0A=
=0A=
- if (ei->try_start <=3D ip && ip <=3D (ei->try_end)) { =0A=
+ /* When making an x-86 CALL, the address of the instruction=0A=
+ * following the CALL is pushed on to the stack. Therefore as we=0A=
+ * unwind the stack, the EIP values we find will not point to the=0A=
+ * CALL instruction but instead point to the instruction after the=0A=
+ * CALL.=0A=
+ *=0A=
+ * The test below is a little odd since ip points to the instruction=0A=
+ * after the CALL that threw the exception. If (ip =3D=3D =
ei->try_start)=0A=
+ * then the CALL which threw the exception came immediately before=0A=
+ * the try block. If (ip =3D=3D ei->try_end) then the CALL which =
threw=0A=
+ * the exception was the last instruction of the try block.=0A=
+ */=0A=
+=0A=
+ if (ei->try_start < ip && ip <=3D ei->try_end) { =0A=
/* catch block */=0A=
if (ei->flags =3D=3D 0 && mono_object_isinst (obj, =0A=
mono_class_get (m->klass->image, ei->token_or_filter))) {=0A=
@@ -188,7 +201,8 @@=0A=
for (i =3D 0; i < ji->num_clauses; i++) {=0A=
MonoJitExceptionInfo *ei =3D &ji->clauses [i];=0A=
=0A=
- if (ei->try_start <=3D ip && ip < (ei->try_end) &&=0A=
+ /* See comment regarding ip above */=0A=
+ if (ei->try_start < ip && ip <=3D ei->try_end &&=0A=
(ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {=0A=
call_finally (ctx, (unsigned long)ei->handler_start);=0A=
}=0A=
------=_NextPart_000_000C_01C1F375.2E9870B0--