[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