[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.

Content-Type: text/plain;
Content-Transfer-Encoding: 7bit

Running NUnitConsole_mono.exe in mono on Windows exposed the following

If an exception were throw by the instruction immediately preceding a
try block, the exception would be considered to be thrown inside the try

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


Content-Type: application/octet-stream;
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;

Index: mono/jit/exception.c=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=
-				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 =
+				 * 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 =
+				 * the exception was the last instruction of the try block.=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=
-				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=