[m-dev.] for review: print/browse exceptions in the debugger

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Sat Jun 17 03:30:58 AEST 2000


Hi,

This is for review by anyone.

Cheers,
Mark.

Estimated hours taken: 5

Allow the value of an exception to be printed and browsed
at EXCP events in the internal debugger.  Two new commands
are added to the debugger:

	print exception
	browse exception

trace/mercury_trace_internal.c:
	Implement the new commands.

runtime/mercury_trace_base.c:
runtime/mercury_trace_base.h:
	Export functions to get/set a global which stores the
	value of an exception for the internal debugger to refer to.

library/exception.m:
	Set the exception value before generating EXCP events.

doc/user_guide.texi:
	Document the new debugger commands.

tests/debugger/Mmakefile:
tests/debugger/exception_value.m:
tests/debugger/exception_value.inp:
tests/debugger/exception_value.exp:
tests/debugger/exception_value.exp2:
	Add a test case.

Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.208
diff -u -r1.208 user_guide.texi
--- doc/user_guide.texi	2000/06/01 08:47:37	1.208
+++ doc/user_guide.texi	2000/06/16 17:13:23
@@ -1981,6 +1981,10 @@
 @item print *
 Prints the values of all the known variables in the current environment.
 @sp 1
+ at item print exception
+Prints the value of the exception at an EXCP port.
+Reports an error if the current event does not refer to such a port.
+ at sp 1
 @item browse @var{name}
 @itemx browse @var{num}
 Invokes an interactive term browser to browse the value of the
@@ -1997,6 +2001,11 @@
 For further documentation on the interactive term browser,
 invoke the @samp{browse} command from within @samp{mdb} and then
 type @samp{help} at the @samp{browser>} prompt.
+ at sp 1
+ at item browse exception
+Invokes the interactive term browser to browse
+the value of the exception at an EXCP port.
+Reports an error if the current event does not refer to such a port.
 @sp 1
 @item stack [-d]
 Prints the names of the ancestors of the call
Index: library/exception.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.23
diff -u -r1.23 exception.m
--- library/exception.m	2000/05/31 12:58:19	1.23
+++ library/exception.m	2000/06/16 17:13:37
@@ -1267,6 +1267,7 @@
 	*/
 	if (MR_trace_enabled) {
 		Code *MR_jumpaddr;
+		MR_trace_set_exception_value(exception);
 		save_transient_registers();
 		MR_jumpaddr = MR_trace_throw(MR_succip, MR_sp, MR_curfr);
 		restore_transient_registers();
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.25
diff -u -r1.25 mercury_trace_base.c
--- runtime/mercury_trace_base.c	2000/06/08 07:59:06	1.25
+++ runtime/mercury_trace_base.c	2000/06/16 17:13:43
@@ -299,6 +299,20 @@
 	}
 }
 
+static	Word		MR_trace_exception_value = (Word) NULL;
+
+void
+MR_trace_set_exception_value(Word exception)
+{
+	MR_trace_exception_value = exception;
+}
+
+Word
+MR_trace_get_exception_value(void)
+{
+	return MR_trace_exception_value;
+}
+
 #ifdef	MR_TRACE_HISTOGRAM
 
 void
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.12
diff -u -r1.12 mercury_trace_base.h
--- runtime/mercury_trace_base.h	1999/12/15 19:11:01	1.12
+++ runtime/mercury_trace_base.h	2000/06/16 17:13:51
@@ -128,6 +128,14 @@
 extern	void	MR_tracing_not_enabled(void);
 
 /*
+** These functions allow library/exceptions.m to tell the debuggers
+** which exception has been thrown.
+*/
+
+extern	void	MR_trace_set_exception_value(Word exception);
+extern	Word	MR_trace_get_exception_value(void);
+
+/*
 ** If MR_TRACE_HISTOGRAM is defined, MR_trace maintains two arrays of integers,
 ** MR_trace_histogram_all and MR_trace_histogram_exp, in which the element
 ** with subscript d is incremented when a trace event occurs at depth d.
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.40
diff -u -r1.40 Mmakefile
--- tests/debugger/Mmakefile	2000/05/22 06:46:12	1.40
+++ tests/debugger/Mmakefile	2000/06/16 17:13:52
@@ -22,6 +22,7 @@
 	browse_pretty			\
 	browser_test			\
 	debugger_regs			\
+	exception_value			\
 	exception_vars			\
 	existential_type_classes	\
 	implied_instance		\
@@ -89,6 +90,13 @@
 
 debugger_regs.out: debugger_regs debugger_regs.inp
 	$(MDB) ./debugger_regs < debugger_regs.inp > debugger_regs.out 2>&1
+
+# We need to pipe the output through sed to avoid hard-coding dependencies on
+# particular line numbers in the standard library source code.
+exception_value.out: exception_value exception_value.inp
+	$(MDB) ./exception_value < exception_value.inp 2>&1 | \
+		sed 's/exception.m:[0-9]*/exception.m:NNNN/g' \
+			> exception_value.out 2>&1
 
 # The exception_vars test is supposed to return a non-zero
 # exit status, since it exits by throwing an exception.
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.67
diff -u -r1.67 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	2000/05/21 06:07:12	1.67
+++ trace/mercury_trace_internal.c	2000/06/16 17:14:35
@@ -176,6 +176,8 @@
 			bool detailed);
 static	void	MR_trace_print_var(Word type_info, Word value);
 static	void	MR_trace_browse_var(Word type_info, Word value);
+static	const char *MR_trace_browse_exception(MR_Event_Info *event_info,
+		MR_Browser browser);
 
 static	const char *MR_trace_read_help_text(void);
 static	bool	MR_trace_is_number(const char *word, int *value);
@@ -424,6 +426,30 @@
 	MR_trace_browse(type_info, value);
 }
 
+static const char *
+MR_trace_browse_exception(MR_Event_Info *event_info, MR_Browser browser)
+{
+	Word		type_info;
+	Word		value;
+	Word		exception;
+
+	if (event_info->MR_trace_port != MR_PORT_EXCEPTION) {
+		return "command only available from EXCP ports";
+	}
+
+	exception = MR_trace_get_exception_value();
+	if (exception == (Word) NULL) {
+		return "missing exception value";
+	}
+
+	type_info = MR_field(MR_mktag(0), exception, UNIV_OFFSET_FOR_TYPEINFO);
+	value = MR_field(MR_mktag(0), exception, UNIV_OFFSET_FOR_DATA);
+
+	(*browser)(type_info, value);
+
+	return (const char *) NULL;
+}
+
 static void
 MR_trace_do_noop(void)
 {
@@ -836,6 +862,9 @@
 			if streq(words[1], "*") {
 				problem = MR_trace_browse_all(MR_mdb_out,
 					MR_trace_print_var);
+			} else if streq(words[1], "exception") {
+				problem = MR_trace_browse_exception(event_info,
+					MR_trace_print_var);
 			} else if (MR_trace_is_number(words[1], &n)) {
 				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NUMBER;
 				var_spec.MR_var_spec_number = n;
@@ -861,7 +890,10 @@
 			const char	*problem;
 			int		n;
 
-			if (MR_trace_is_number(words[1], &n)) {
+			if streq(words[1], "exception") {
+				problem = MR_trace_browse_exception(event_info,
+					MR_trace_browse_var);
+			} else if (MR_trace_is_number(words[1], &n)) {
 				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NUMBER;
 				var_spec.MR_var_spec_number = n;
 				problem = MR_trace_browse_one(NULL, var_spec,


New file: tests/debugger/exception_value.m

:- module exception_value.

:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is cc_multi.

:- implementation.

:- import_module std_util, exception, list.

main -->
	{ test1(Res1) },
	print(Res1),
	io__nl,
	{ test2(Res2) },
	print(Res2),
	io__nl.

:- pred test1(exception_result(int)::out) is cc_multi.
test1(Res) :-
	try(p, Res).

:- pred test2(exception_result(int)::out) is cc_multi.
test2(Res) :-
	try(q, Res).

:- pred p(int::out) is det.

p(_) :-
	throw("p exception").

:- pred q(int::out) is det.

q(_) :-
	throw("q oops" - [1, 2, 3]).


New file: tests/debugger/exception_value.inp

echo on
register --quiet
break p
break q
continue
finish
print exception
continue
finish
browse exception
set depth 9
set size 99
ls
quit
continue


New file: tests/debugger/exception_value.exp

       1:      1  1 CALL pred exception_value:main/2-0 (cc_multi) exception_value.m:12
mdb> echo on
Command echo enabled.
mdb> register --quiet
mdb> break p
 0: + stop  interface pred exception_value:p/1-0 (det)
mdb> break q
 1: + stop  interface pred exception_value:q/1-0 (det)
mdb> continue
       3:      3  3 CALL pred exception_value:p/1-0 (det) exception_value.m:30
mdb> finish
       4:      3  3 EXCP pred exception_value:p/1-0 (det) exception_value.m:31
mdb> print exception
	"p exception"
mdb> continue
mdb: warning: reached unknown label
This may result in some exception events
being omitted from the trace.
exception(univ("p exception" : string))
       7:      5  3 CALL pred exception_value:q/1-0 (det) exception_value.m:35
mdb> finish
       8:      5  3 EXCP pred exception_value:q/1-0 (det) exception_value.m:36
mdb> browse exception
browser> set depth 9
browser> set size 99
browser> ls
-
1-"q oops"
2-.
  1-1
  2-.
    1-2
    2-.
      1-3
      2-[]

browser> quit
mdb> continue
mdb: warning: reached unknown label
This may result in some exception events
being omitted from the trace.
exception(univ("q oops" - [1, 2, 3] : std_util:pair(string, list:list(int))))


New file: tests/debugger/exception_value.exp2

       1:      1  1 CALL pred exception_value:main/2-0 (cc_multi) exception_value.m:12
mdb> echo on
Command echo enabled.
mdb> register --quiet
mdb> break p
 0: + stop  interface pred exception_value:p/1-0 (det)
mdb> break q
 1: + stop  interface pred exception_value:q/1-0 (det)
mdb> continue
       4:      4  4 CALL pred exception_value:p/1-0 (det) exception_value.m:30 (exception.m:NNNN)
mdb> finish
       7:      4  4 EXCP pred exception_value:p/1-0 (det) exception_value.m:31 (exception.m:NNNN)
mdb> print exception
	"p exception"
mdb> continue
exception(univ("p exception" : string))
      18:     11  4 CALL pred exception_value:q/1-0 (det) exception_value.m:35 (exception.m:NNNN)
mdb> finish
      21:     11  4 EXCP pred exception_value:q/1-0 (det) exception_value.m:36 (exception.m:NNNN)
mdb> browse exception
browser> set depth 9
browser> set size 99
browser> ls
-
1-"q oops"
2-.
  1-1
  2-.
    1-2
    2-.
      1-3
      2-[]

browser> quit
mdb> continue
exception(univ("q oops" - [1, 2, 3] : std_util:pair(string, list:list(int))))

-- 
Mark Brown, PhD student            )O+  |  "Another of Fortran's breakthroughs
(m.brown at cs.mu.oz.au)                   |  was the GOTO statement, which was...
Dept. of Computer Science and Software  |  uniquely simple and understandable"
Engineering, University of Melbourne    |              -- IEEE, 1994
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list