for review: mdb support for exceptions

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Dec 9 22:44:43 AEDT 1998


Hi,

Could someone (Mark?) please review this one for me?

--------------------

Estimated hours taken: 8

Add support for exceptions to the debugger, and
add support for debugging to the exception module.

browser/debugger_interface.m:
	Add `exception' to the trace_port_type enumeration.

runtime/mercury_trace_base.h:
	Add MR_PORT_EXCEPTION to the MR_Trace_Port enumeration.

trace/mercury_trace_internal.c:
trace/mercury_trace.h:
trace/mercury_trace.c:
	Modify the code to handle MR_PORT_EXCEPTION.

extras/exceptions/exception.m:
	- Define stack layout structures for the hand-written procedures
	  `builtin_throw' and `builtin_catch'.
	- Use mktempframe() rather than mkframe() to allocate the temporary
	  frames used to prevent hijacking of the exception-catching frame
	  (this is more efficient, and avoids the need to give a stack
	  layout for those frames).
	- Change the code for builtin_throw/1 so that if MR_trace_enabled
	  is true, it calls a new function trace_throw(), which calls
	  MR_trace(..., MR_PORT_EXCEPTION, ...) for each stack frame.
	- Fix some type errors occurring for non-GC grades.
	- Fix some uses of obsolete names (e.g. replace `hp' with `MR_hp').
	
runtime/mercury_trace_base.c:
compiler/trace.m:
	Add some comments relating to the above changes.

--- ../mercury-compiler-0.8/browser/debugger_interface.m	Fri Oct 16 16:16:50 1998
+++ browser/debugger_interface.m	Sat Nov 21 03:52:09 1998
@@ -56,6 +56,7 @@
 	;	switch
 	;	nondet_pragma_first
 	;	nondet_pragma_later
+	;	exception
 	.
 
 :- type goal_path_string == string.
--- ../mercury-compiler-0.8/compiler/trace.m	Mon Nov 16 00:34:12 1998
+++ compiler/trace.m	Sat Nov 21 03:51:54 1998
@@ -52,7 +52,7 @@
 	% The kinds of external ports for which the code we generate will
 	% call MR_trace. The redo port is not on this list, because for that
 	% port the code that calls MR_trace is not in compiler-generated code,
-	% but in the runtime system.
+	% but in the runtime system.  Likewise for the exception port.
 :- type external_trace_port
 	--->	call
 	;	exit
--- ../mercury-compiler-0.8/extras/exceptions/exception.m	Thu Jul 23 00:31:59 1998
+++ extras/exceptions/exception.m	Wed Dec  9 12:24:32 1998
@@ -471,13 +471,96 @@
 
 :- pragma c_code("
 
+Define_extern_entry(exception_handler_do_fail);
+
+/*
+** MR_trace_throw():
+**	Unwind the stack as far as possible, until we reach a frame
+**	with an exception handler.  As we go, invoke
+**	`MR_trace(..., MR_PORT_EXCEPTION, ...)' for each stack frame,
+**	to signal to the debugger that that procedure has exited via
+**	an exception.  This allows to user to use the `retry' command
+**	to restart a goal which exited via an exception.
+**
+**	Note that if MR_STACK_TRACE is not defined, then we may not be
+**	able to traverse the stack all the way; in that case, we just
+**	print a warning and then continue.  It might be better to just
+**	`#ifdef' out all this code (and the code in builtin_throw which
+**	calls it) if MR_STACK_TRACE is not defined.
+*/
+
+#define WARNING(msg)							\\
+	fprintf(stderr, ""mdb: warning: %s\\n""				\\
+		""This may result in some exception events\\n""		\\
+		""being omitted from the trace.\\n"", (msg))
+
+static Code *
+MR_trace_throw(Code *success_pointer, Word *det_stack_pointer,
+	Word *current_frame)
+{
+	const MR_Internal		*label;
+	const MR_Stack_Layout_Label	*return_label_layout;
+
+	/*
+	** Find the layout info for the stack frame pointed to by MR_succip
+	*/
+	label = MR_lookup_internal_by_addr(success_pointer);
+	if (label == NULL) {
+		WARNING(""internal label not found\\n"");
+		return NULL;
+	}
+	return_label_layout = label->i_layout;
+
+	while (return_label_layout != NULL) {
+		const MR_Stack_Layout_Entry	*entry_layout;
+		Code 				*MR_jumpaddr;
+		MR_Stack_Walk_Step_Result	result;
+		const char			*problem;
+
+		/*
+		** check if we've reached a frame with an exception handler
+		*/
+		entry_layout = return_label_layout->MR_sll_entry;
+		if (!MR_DETISM_DET_STACK(entry_layout->MR_sle_detism)
+		    && MR_redoip_slot(current_frame) ==
+			ENTRY(exception_handler_do_fail))
+		{
+			return NULL;
+		}
+
+		/*
+		** invoke MR_trace() to trace the exception
+		*/
+		MR_jumpaddr = MR_trace(return_label_layout, MR_PORT_EXCEPTION,
+			"""", 0);
+		if (MR_jumpaddr != NULL) {
+			return MR_jumpaddr;
+		}
+
+		/*
+		** unwind the stacks back to the previous stack frame
+		*/
+		result = MR_stack_walk_step(entry_layout, &return_label_layout,
+			&det_stack_pointer, &current_frame, &problem);
+		if (result != STEP_OK) {
+			WARNING(problem);
+			return NULL;
+		}
+		restore_transient_registers();
+		MR_sp = det_stack_pointer;
+		MR_curfr = current_frame;
+		save_transient_registers();
+	}
+	return NULL;
+}
+
 enum CodeModel { MODEL_DET, MODEL_SEMI, MODEL_NON };
 
 /* swap the heap with the solutions heap */
 #define swap_heaps()							\\
 {									\\
 	/* save the current heap */					\\
-	Word *swap_heaps_temp_hp = hp;					\\
+	Word *swap_heaps_temp_hp = MR_hp;				\\
 	MemoryZone *swap_heaps_temp_hp_zone = MR_heap_zone;		\\
 									\\
 	/* set heap to solutions heap */				\\
@@ -503,14 +586,14 @@
 	Word ticket_counter;
 #endif
 #ifndef CONSERVATIVE_GC
-	Word heap_ptr;
-	Word solns_heap_ptr;
-	Word heap_zone;
+	Word *heap_ptr;
+	Word *solns_heap_ptr;
+	MemoryZone *heap_zone;
 #endif
 } Exception_Handler_Frame;
 
-#define FRAMEVARS \
-	(((Exception_Handler_Frame *) (curfr - NONDET_FIXED_SIZE)) - 1)
+#define FRAMEVARS \\
+	(((Exception_Handler_Frame *) (MR_curfr - MR_NONDET_FIXED_SIZE)) - 1)
 
 Define_extern_entry(mercury__exception__builtin_catch_3_0); /* det */
 Define_extern_entry(mercury__exception__builtin_catch_3_1); /* semidet */
@@ -521,75 +604,88 @@
 
 Define_extern_entry(mercury__exception__builtin_throw_1_0);
 
-Define_extern_entry(exception_handler_do_fail);
-
 /* the following are defined in runtime/mercury_ho_call.c */
 Declare_entry(do_call_det_closure);
 Declare_entry(do_call_semidet_closure);
 Declare_entry(do_call_nondet_closure);
 
-Declare_label(mercury__exception__builtin_catch_3_2_i1);
+/* the following is defined in runtime/mercury_trace_base.c */
+Declare_entry(MR_do_trace_redo_fail);
+
 Declare_label(mercury__exception__builtin_catch_3_2_i2);
-Declare_label(mercury__exception__builtin_catch_3_3_i1);
 Declare_label(mercury__exception__builtin_catch_3_3_i2);
-Declare_label(mercury__exception__builtin_catch_3_5_i1);
 Declare_label(mercury__exception__builtin_catch_3_5_i2);
 #ifdef MR_USE_TRAIL
   Declare_label(mercury__exception__builtin_catch_3_5_i3);
 #endif
-#ifndef COMPACT_ARGS
-  Declare_label(mercury__exception__builtin_throw_1_0_i1);
-  Declare_label(mercury__exception__builtin_throw_1_0_i2);
-  Declare_label(mercury__exception__builtin_throw_1_0_i3);
-#endif
-
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_0)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_1)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_2)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_3)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_4)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_5)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_throw_1_0)
-MR_MAKE_STACK_LAYOUT_ENTRY(exception_handler_do_fail)
-MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_0)
-
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_2, 1)
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_2, 2)
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_3, 1)
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_3, 2)
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 1)
-MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 2)
-#ifdef MR_USE_TRAIL
-  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 3)
+Declare_label(mercury__exception__builtin_throw_1_0_i1);
+
+#ifdef COMPACT_ARGS
+  #define BUILTIN_THROW_STACK_SIZE 1
+#else
+  #define BUILTIN_THROW_STACK_SIZE 2
 #endif
+
+
+/*
+** MR_MAKE_PROC_LAYOUT(entry, detism, slots, succip_locn, pred_or_func,
+**			module, name, arity, mode)                         
+*/
+/* do we need one for exception_handler_do_fail? */
+
+MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_throw_1_0,
+        MR_DETISM_DET, BUILTIN_THROW_STACK_SIZE, MR_LIVE_LVAL_STACKVAR(1),
+        MR_PREDICATE, ""exception"", ""builtin_throw"", 1, 0);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_throw_1_0, 1);
 #ifndef COMPACT_ARGS
-  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 1)
-  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 2)
-  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 3)
+  MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_throw_1_0, 2);
+  MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_throw_1_0, 3);
+#endif
+
+/*
+** The following procedures all allocate their stack frames on
+** the nondet stack, so for the purposes of doing stack traces
+** we say they have MR_DETISM_NON, even though they are not
+** actually nondet.
+*/ 
+MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_2,
+	MR_DETISM_NON,	/* really cc_multi; also used for det */
+	MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN,
+	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 2);
+MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_3,
+	MR_DETISM_NON,	/* really cc_nondet; also used for semidet */
+	MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN,
+	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 3);
+MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_5,
+	MR_DETISM_NON,	/* ; also used for multi */
+	MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN,
+	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 5);
+
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 1);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 2);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 1);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 2);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 1);
+MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 2);
+#ifdef MR_USE_TRAIL
+  MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 3);
 #endif
 
 BEGIN_MODULE(exceptions_module)
 	init_entry(mercury__exception__builtin_catch_3_0);
 	init_entry(mercury__exception__builtin_catch_3_1);
-	init_entry(mercury__exception__builtin_catch_3_2);
-	init_entry(mercury__exception__builtin_catch_3_3);
+	init_entry_sl(mercury__exception__builtin_catch_3_2);
+	init_entry_sl(mercury__exception__builtin_catch_3_3);
 	init_entry(mercury__exception__builtin_catch_3_4);
-	init_entry(mercury__exception__builtin_catch_3_5);
-	init_label(mercury__exception__builtin_catch_3_2_i1);
-	init_label(mercury__exception__builtin_catch_3_2_i2);
-	init_label(mercury__exception__builtin_catch_3_3_i1);
-	init_label(mercury__exception__builtin_catch_3_3_i2);
-	init_label(mercury__exception__builtin_catch_3_5_i1);
-	init_label(mercury__exception__builtin_catch_3_5_i2);
+	init_entry_sl(mercury__exception__builtin_catch_3_5);
+	init_label_sl(mercury__exception__builtin_catch_3_2_i2);
+	init_label_sl(mercury__exception__builtin_catch_3_3_i2);
+	init_label_sl(mercury__exception__builtin_catch_3_5_i2);
 #ifdef MR_USE_TRAIL
 	init_label(mercury__exception__builtin_catch_3_5_i3);
 #endif
 	init_entry(mercury__exception__builtin_throw_1_0);
-#ifndef COMPACT_ARGS
 	init_label(mercury__exception__builtin_throw_1_0_i1);
-	init_label(mercury__exception__builtin_throw_1_0_i2);
-	init_label(mercury__exception__builtin_throw_1_0_i3);
-#endif
 	init_entry(exception_handler_do_fail);
 BEGIN_CODE
 
@@ -650,8 +746,7 @@
 	** can avoid this by creating a second frame above the special
 	** frame.)
 	*/
-	succip = LABEL(mercury__exception__builtin_catch_3_2_i1);
-	mkframe(""builtin_catch_2/1 [model_det]"", 0, ENTRY(do_fail));
+	mktempframe(ENTRY(do_fail));
 
 	/*
 	** Now call `Goal(Result)'.
@@ -676,9 +771,6 @@
 #endif
 	succeed_discard();
 
-Define_label(mercury__exception__builtin_catch_3_2_i1);
-	succeed_discard();
-
 /*
 ** builtin_catch(Goal, Handler, Result)
 **	call Goal(R).
@@ -747,8 +839,7 @@
 	** can avoid this by creating a second frame above the special
 	** frame.)
 	*/
-	succip = LABEL(mercury__exception__builtin_catch_3_3_i1);
-	mkframe(""builtin_catch_2/1 [model_semi]"", 0, ENTRY(do_fail));
+	mktempframe(ENTRY(do_fail));
 
 	/*
 	** Now call `Goal(Result)'.
@@ -781,9 +872,6 @@
 #endif
 	succeed_discard();
 
-Define_label(mercury__exception__builtin_catch_3_3_i1);
-	succeed_discard();
-
 /*
 ** builtin_catch(Goal, Handler, Result)
 **	call Goal(R).
@@ -842,12 +930,10 @@
 	** can avoid this by creating a second frame above the special
 	** frame.)
 	*/
-	succip = LABEL(mercury__exception__builtin_catch_3_5_i1);
 #ifdef MR_USE_TRAIL
-	mkframe(""builtin_catch_2/1 [nondet]"", 0,
-		LABEL(mercury__exception__builtin_catch_3_5_i3));
+	mktempframe(LABEL(mercury__exception__builtin_catch_3_5_i3));
 #else
-	mkframe(""builtin_catch_2/1 [nondet]"", 0, ENTRY(do_fail));
+	mktempframe(ENTRY(do_fail));
 #endif
 
 	/*
@@ -876,9 +962,6 @@
 	*/
 	succeed();
 
-Define_label(mercury__exception__builtin_catch_3_5_i1);
-	succeed();
-
 #ifdef MR_USE_TRAIL
 Define_label(mercury__exception__builtin_catch_3_5_i3);
 	MR_discard_ticket();
@@ -900,20 +983,33 @@
 	enum CodeModel catch_code_model;
 
 	/*
+	** let the debugger trace exception throwing
+	*/
+	if (MR_trace_enabled) {
+		Code *MR_jumpaddr;
+		save_transient_registers();
+		MR_jumpaddr = MR_trace_throw(MR_succip, MR_sp, MR_curfr);
+		restore_transient_registers();
+		if (MR_jumpaddr != NULL) GOTO(MR_jumpaddr);
+	}
+
+	/*
 	** Search the nondet stack for an exception handler,
 	** i.e. a frame whose redoip is `exception_handler_do_fail'
 	** (one created by `builtin_catch').
 	** N.B.  We search down the `succfr' chain, not the `prevfr' chain;
 	** this ensures that we only find handlers installed by our callers,
 	** not handlers installed by procedures that we called but which
-	** are still on the nondet stack because they choice points behind.
+	** are still on the nondet stack because they left choice points
+	** behind.
 	*/
-	do {
-		MR_curfr = cursuccfr;
+	while (MR_redoip_slot(MR_curfr) != ENTRY(exception_handler_do_fail)) {
+		MR_curfr = MR_succfr_slot(MR_curfr);
 		if (MR_curfr < MR_CONTEXT(nondetstack_zone)->min) {
 			fatal_error(""builtin_throw/1: uncaught exception"");
 		}
-	} while (curredoip != ENTRY(exception_handler_do_fail));
+
+	}
 
 	/*
 	** Save the handler we found, and reset the det stack top.
@@ -962,8 +1058,8 @@
 	*/
 	assert(FRAMEVARS->heap_ptr <= FRAMEVARS->heap_zone->top);
 	save_transient_registers();
-	exception = deep_copy(exception,
-		(Word *) (Word) &mercury_data_std_util__base_type_info_univ_0,
+	exception = deep_copy((Word *) exception,
+		(Word *) &mercury_data_std_util__base_type_info_univ_0,
 		FRAMEVARS->heap_ptr, FRAMEVARS->heap_zone->top);
 	restore_transient_registers();
 
@@ -977,8 +1073,8 @@
 	/* deep_copy the exception back to the ordinary heap */
 	assert(FRAMEVARS->solns_heap_ptr <= MR_solutions_heap_zone->top);
 	save_transient_registers();
-	exception = deep_copy(exception,
-		(Word *) (Word) &mercury_data_std_util__base_type_info_univ_0,
+	exception = deep_copy((Word *) exception,
+		(Word *) &mercury_data_std_util__base_type_info_univ_0,
 		saved_solns_heap_ptr, MR_solutions_heap_zone->top);
 	restore_transient_registers();
 
@@ -1013,7 +1109,7 @@
 	** and reset the nondet stack top.  (This must be done last,
 	** since it invalidates all the framevars.)
 	*/
-	MR_maxfr = curprevfr;
+	MR_maxfr = MR_prevfr_slot(MR_curfr);
 	MR_curfr = MR_maxfr;
 
 	/*
@@ -1036,7 +1132,8 @@
 		tailcall(ENTRY(do_call_det_closure), 
 			ENTRY(mercury__exception__builtin_throw_1_0));
 	}
-	push(succip);
+	incr_sp_push_msg(1, ""builtin_throw/1"");
+	MR_stackvar(1) = (Word) MR_succip;
 	call(ENTRY(do_call_det_closure), 
 		LABEL(mercury__exception__builtin_throw_1_0_i1),
 		ENTRY(mercury__exception__builtin_throw_1_0));
@@ -1046,13 +1143,15 @@
 	/* we've just returned from do_call_det_closure */
 	r2 = r1;
 	r1 = TRUE;
-	succip = (Code *) pop();
+	MR_succip = (Code *) MR_succip;
+	decr_sp_pop_msg(1);
 	proceed();
 
 #else /* not COMPACT_ARGS */
 
-	push(succip);
-	push(catch_code_model);
+	incr_sp_push_msg(2, ""builtin_throw/1"");
+	MR_stackvar(1) = (Word) MR_succip;
+	MR_stackvar(2) = catch_code_model;
 	call(ENTRY(do_call_det_closure), 
 		LABEL(mercury__exception__builtin_throw_1_0_i1)),
 		ENTRY(mercury__exception__builtin_throw_1_0));
@@ -1060,13 +1159,14 @@
 Define_label(mercury__exception__builtin_throw_1_0_i1);
 	update_prof_current_proc(LABEL(mercury__exception__builtin_throw_1_0));
 	/* we've just returned from do_call_det_closure */
-	catch_code_model = pop();
+	catch_code_model = MR_stackvar(2);
 	if (catch_code_model == MODEL_SEMI) {
 		r5 = r1;
 	else {
 		r4 = r1;
 	}
-	succip = (Code *) pop();
+	succip = (Code *) MR_stackvar(1);
+	decr_sp_pop_msg(2);
 	proceed();
 
 #endif /* not COMPACT_ARGS */
--- ../mercury-compiler-0.8/runtime/mercury_trace_base.c	Thu Nov 12 00:30:48 1998
+++ runtime/mercury_trace_base.c	Sat Nov 21 03:55:00 1998
@@ -281,6 +281,10 @@
 	printf("MR_redo_layout_framevar(MR_redofr_slot(MR_curfr) = %p\n",
 		MR_redo_layout_framevar(MR_redofr_slot(MR_curfr)));
 #endif
+	/*
+	** If this code ever needs changing, you may also need to change
+	** the code in extras/exceptions/exception.m similarly.
+	*/
 	{
 		Code *MR_jumpaddr;
 		save_transient_registers();
--- ../mercury-compiler-0.8/runtime/mercury_trace_base.h	Tue Nov 10 00:31:33 1998
+++ runtime/mercury_trace_base.h	Sat Nov 21 03:50:46 1998
@@ -34,7 +34,8 @@
 	MR_PORT_DISJ,
 	MR_PORT_SWITCH,
 	MR_PORT_PRAGMA_FIRST,
-	MR_PORT_PRAGMA_LATER
+	MR_PORT_PRAGMA_LATER,
+	MR_PORT_EXCEPTION
 } MR_Trace_Port;
 
 #define MR_trace_incr_seq()		((Word) ++MR_trace_call_seqno)
--- ../mercury-compiler-0.8/trace/mercury_trace.c	Fri Oct 16 16:20:08 1998
+++ trace/mercury_trace.c	Sat Nov 21 04:00:53 1998
@@ -125,7 +125,10 @@
 			}
 
 		case MR_CMD_RESUME_FORWARD:
-			if (! (port == MR_PORT_REDO || port == MR_PORT_FAIL)) {
+			if (port != MR_PORT_REDO &&
+			    port != MR_PORT_FAIL &&
+			    port != MR_PORT_EXCEPTION)
+			{
 				return MR_trace_event(&MR_trace_ctrl, TRUE,
 						layout, port, seqno, depth,
 						path, max_r_num);
--- ../mercury-compiler-0.8/trace/mercury_trace.h	Fri Oct 16 16:20:09 1998
+++ trace/mercury_trace.h	Tue Dec  8 15:42:16 1998
@@ -30,10 +30,10 @@
 **
 ** If MR_trace_cmd == MR_CMD_FINISH, the event handler will stop at the next
 ** event that specifies the procedure invocation whose call number is in
-** MR_trace_stop_seqno and whose port is EXIT or FAIL.
+** MR_trace_stop_seqno and whose port is EXIT or FAIL or EXCEPTION.
 **
 ** If MR_trace_cmd == MR_CMD_RESUME_FORWARD, the event handler will stop at
-** the next event of any call whose port is *not* REDO or FAIL.
+** the next event of any call whose port is *not* REDO or FAIL or EXCEPTION.
 **
 ** If MR_trace_cmd == MR_CMD_RETURN, the event handler will stop at
 ** the next event of any call whose port is *not* EXIT.
@@ -83,9 +83,11 @@
 } MR_Trace_Cmd_Info;
 
 #define	MR_port_is_final(port)		((port) == MR_PORT_EXIT || \
-					(port) == MR_PORT_FAIL)
+					 (port) == MR_PORT_FAIL || \
+					 (port) == MR_PORT_EXCEPTION)
 
-#define	MR_port_is_interface(port)	((port) < MR_PORT_FAIL)
+#define	MR_port_is_interface(port)	((port) < MR_PORT_FAIL || \
+					 (port) == MR_PORT_EXCEPTION)
 
 #define	MR_port_is_entry(port)		((port) == MR_PORT_CALL)
 
--- ../mercury-compiler-0.8/trace/mercury_trace_internal.c	Mon Nov 16 04:58:48 1998
+++ trace/mercury_trace_internal.c	Sat Nov 21 04:02:48 1998
@@ -514,7 +514,10 @@
 		{
 			; /* the usage message has already been printed */
 		} else if (word_count == 1) {
-			if (port == MR_PORT_FAIL || port == MR_PORT_REDO) {
+			if (port == MR_PORT_FAIL ||
+			    port == MR_PORT_REDO ||
+			    port == MR_PORT_EXCEPTION)
+			{
 				cmd->MR_trace_cmd = MR_CMD_RESUME_FORWARD;
 				goto return_stop_interacting;
 			} else {
@@ -2381,6 +2384,10 @@
 
 		case MR_PORT_PRAGMA_LATER:
 			printf("LATR ");
+			break;
+
+		case MR_PORT_EXCEPTION:
+			printf("EXCP ");
 			break;
 
 		default:

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"
PGP: finger fjh at 128.250.37.3        |     -- leaked Microsoft memo.



More information about the developers mailing list