[m-dev.] for review: record trace level in the module layout structure
Mark Anthony BROWN
dougl at cs.mu.OZ.AU
Thu Nov 9 18:36:40 AEDT 2000
Hi,
This addresses a problem that was brought to my attention by
Rob Jeschofnik -- the declarative debugger is a little unfriendly
if you forget to compile with the right trace level.
This is for review by anyone.
Cheers,
Mark.
Estimated hours taken: 3
Record the trace level that the module was compiled with in the module
layout structure. Use this to avoid an abort if the 'dd' command is used
on a module that is compiled with trace level 'deep'.
compiler/trace_params.m:
Encode the trace level as an integer.
runtime/mercury_stack_layout.h:
Add a field to MR_Module_Layout to store the encoded trace level.
compiler/stack_layout.m:
Fill in this field.
trace/mercury_trace_declarative.c:
Ignore events from modules that don't have an appropriate trace
level. This effectively assumes that the events are correct, so
we warn the user that this has happened. Also, disallow the 'dd'
command at these events.
tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/deep_sub.m:
tests/debugger/declarative/deep_warning.exp:
tests/debugger/declarative/deep_warning.inp:
tests/debugger/declarative/deep_warning.m:
A test case for the new feature.
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.56
diff -u -r1.56 stack_layout.m
--- compiler/stack_layout.m 2000/10/16 01:33:37 1.56
+++ compiler/stack_layout.m 2000/11/09 06:16:04
@@ -386,7 +386,8 @@
yes(const(int_const(NumProcLayouts))),
yes(ProcLayoutVector),
yes(const(int_const(NumSourceFiles))),
- yes(SourceFileVectors)],
+ yes(SourceFileVectors),
+ yes(const(int_const(trace_level_rep(TraceLevel))))],
ModuleLayouts = comp_gen_c_data(ModuleName, module_layout,
Exported, Rvals, uniform(no), []),
StaticLayouts = [ModuleLayouts | InternalLayouts]
Index: compiler/trace_params.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trace_params.m,v
retrieving revision 1.2
diff -u -r1.2 trace_params.m
--- compiler/trace_params.m 2000/10/04 04:24:35 1.2
+++ compiler/trace_params.m 2000/11/09 06:16:08
@@ -41,6 +41,9 @@
:- func trace_level_none = trace_level.
+ % This is used to represent the trace level in the module layout.
+:- func trace_level_rep(trace_level) = int.
+
:- implementation.
:- import_module char, string, list, set.
@@ -226,6 +229,14 @@
:- pred wrap_port(trace_port::in, trace_suppress_item::out) is det.
wrap_port(Port, port(Port)).
+
+ % If this is modified, then the corresponding code in
+ % runtime/mercury_stack_layout.h needs to be updated.
+trace_level_rep(none) = 0.
+trace_level_rep(shallow) = 1.
+trace_level_rep(deep) = 2.
+trace_level_rep(decl) = 3.
+trace_level_rep(decl_rep) = 4.
%-----------------------------------------------------------------------------%
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.42
diff -u -r1.42 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h 2000/11/07 08:58:35 1.42
+++ runtime/mercury_stack_layout.h 2000/11/09 06:16:18
@@ -580,6 +580,19 @@
** require padding.) The labels are sorted on line number.
*/
+/*
+** The trace level that the module was compiled with. If this enum is
+** modified, then the corresponding function in compiler/trace_params.m
+** must be updated.
+*/
+typedef enum {
+ MR_TRACE_LEVEL_NONE,
+ MR_TRACE_LEVEL_SHALLOW,
+ MR_TRACE_LEVEL_DEEP,
+ MR_TRACE_LEVEL_DECL,
+ MR_TRACE_LEVEL_DECL_REP
+} MR_Trace_Level;
+
typedef struct MR_Module_File_Layout_Struct {
MR_String MR_mfl_filename;
MR_Integer MR_mfl_label_count;
@@ -596,6 +609,7 @@
MR_Stack_Layout_Entry **MR_ml_procs;
MR_Integer MR_ml_filename_count;
MR_Module_File_Layout **MR_ml_module_file_layout;
+ MR_Trace_Level MR_ml_trace_level;
} MR_Module_Layout;
#endif /* not MERCURY_STACK_LAYOUT_H */
Index: tests/debugger/declarative/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mmakefile,v
retrieving revision 1.22
diff -u -r1.22 Mmakefile
--- tests/debugger/declarative/Mmakefile 2000/11/01 04:26:30 1.22
+++ tests/debugger/declarative/Mmakefile 2000/11/09 06:16:22
@@ -24,6 +24,7 @@
backtrack \
big \
comp_gen \
+ deep_warning \
family \
filter \
func_call \
@@ -51,6 +52,7 @@
MLFLAGS = --trace
C2INITFLAGS = --trace
+MCFLAGS-deep_sub=--trace deep
MCFLAGS-untraced_subgoal_sub=--trace minimum
ifneq "$(findstring .debug,$(GRADE))" ""
@@ -105,6 +107,9 @@
comp_gen.out: comp_gen comp_gen.inp
$(MDB) ./comp_gen < comp_gen.inp > comp_gen.out 2>&1
+
+deep_warning.out: deep_warning deep_warning.inp
+ $(MDB) ./deep_warning < deep_warning.inp > deep_warning.out 2>&1
family.out: family family.inp
$(MDB) ./family < family.inp > family.out 2>&1
Index: tests/debugger/declarative/deep_sub.m
===================================================================
RCS file: deep_sub.m
diff -N deep_sub.m
--- /dev/null Sat Aug 7 21:45:41 1999
+++ deep_sub.m Thu Nov 9 17:16:23 2000
@@ -0,0 +1,7 @@
+:- module deep_sub.
+:- interface.
+:- pred q(int::out) is multi.
+:- implementation.
+q(1).
+q(2).
+
Index: tests/debugger/declarative/deep_warning.exp
===================================================================
RCS file: deep_warning.exp
diff -N deep_warning.exp
--- /dev/null Sat Aug 7 21:45:41 1999
+++ deep_warning.exp Thu Nov 9 17:16:23 2000
@@ -0,0 +1,33 @@
+ 1: 1 1 CALL pred deep_warning:main/2-0 (det) deep_warning.m:8
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break p
+ 0: + stop interface pred deep_warning:p/2-0 (nondet)
+mdb> break q
+ 1: + stop interface pred deep_sub:q/1-0 (multi)
+mdb> continue
+ 3: 2 2 CALL pred deep_warning:p/2-0 (nondet) deep_warning.m:28 (deep_warning.m:10)
+mdb> finish
+ 5: 3 3 CALL pred deep_sub:q/1-0 (multi) deep_sub.m:5 (deep_warning.m:29)
+ 7: 3 3 EXIT pred deep_sub:q/1-0 (multi) deep_sub.m:5 (deep_warning.m:29)
+ 8: 2 2 EXIT pred deep_warning:p/2-0 (nondet) deep_warning.m:28 (deep_warning.m:10)
+mdb> dd
+Warning: some modules were compiled with a trace level lower than `decl'.
+This may result in calls being omitted from the debugging tree.
+p(1, 1)
+Valid? no
+Found incorrect contour:
+p(1, 1)
+Is this a bug? yes
+ 8: 2 2 EXIT pred deep_warning:p/2-0 (nondet) deep_warning.m:28 (deep_warning.m:10)
+mdb> retry
+ 3: 2 2 CALL pred deep_warning:p/2-0 (nondet) deep_warning.m:28 (deep_warning.m:10)
+mdb> continue
+ 5: 3 3 CALL pred deep_sub:q/1-0 (multi) deep_sub.m:5 (deep_warning.m:29)
+mdb> finish
+ 7: 3 3 EXIT pred deep_sub:q/1-0 (multi) deep_sub.m:5 (deep_warning.m:29)
+mdb> dd
+mdb: cannot start declarative debugging, because this procedure was not
+compiled with trace level `decl'.
+mdb> quit -y
Index: tests/debugger/declarative/deep_warning.inp
===================================================================
RCS file: deep_warning.inp
diff -N deep_warning.inp
--- /dev/null Sat Aug 7 21:45:41 1999
+++ deep_warning.inp Thu Nov 9 17:16:23 2000
@@ -0,0 +1,14 @@
+echo on
+register --quiet
+break p
+break q
+continue
+finish
+dd
+no
+yes
+retry
+continue
+finish
+dd
+quit -y
Index: tests/debugger/declarative/deep_warning.m
===================================================================
RCS file: deep_warning.m
diff -N deep_warning.m
--- /dev/null Sat Aug 7 21:45:41 1999
+++ deep_warning.m Thu Nov 9 17:16:24 2000
@@ -0,0 +1,44 @@
+:- module deep_warning.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+:- implementation.
+:- import_module int, deep_sub.
+
+main -->
+ (
+ { p(1, X) },
+ { X > 10 }
+ ->
+ io__write_string("yes\n")
+ ;
+ io__write_string("no\n")
+ ),
+ (
+ { p(2, Y) },
+ { Y > 10 }
+ ->
+ io__write_string("yes\n")
+ ;
+ io__write_string("no\n")
+ ).
+
+:- pred p(int::in, int::out) is nondet.
+
+p(1, X) :-
+ deep_sub__q(X).
+
+p(2, X) :-
+ deep_sub__q(X),
+ r(X, Y),
+ s(Y).
+
+:- pred r(int::in, int::out) is det.
+
+r(X, X).
+
+:- pred s(int::out) is multi.
+
+s(2).
+s(3).
+
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.32
diff -u -r1.32 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c 2000/10/16 01:34:10 1.32
+++ trace/mercury_trace_declarative.c 2000/11/09 06:16:57
@@ -115,10 +115,20 @@
static MR_Unsigned MR_edt_max_depth;
static MR_Unsigned MR_edt_last_event;
-static bool MR_edt_inside;
+static MR_Bool MR_edt_inside;
static MR_Unsigned MR_edt_start_seqno;
/*
+** The declarative debugger ignores modules that were not compiled with
+** the required information. However, this may result in incorrect
+** assumptions being made about the code, so the debugger gives a warning
+** if this happens. The following flag indicates whether a warning
+** should be printed before calling the front end.
+*/
+
+static MR_Bool MR_edt_compiler_flag_warning;
+
+/*
** This is used as the abstract map from node identifiers to nodes
** in the data structure passed to the front end. It should be
** incremented each time the data structure is destructively
@@ -283,6 +293,7 @@
MR_Unsigned depth;
MR_Trace_Node trace;
MR_Event_Details event_details;
+ MR_Trace_Level trace_level;
entry = event_info->MR_event_sll->MR_sll_entry;
depth = event_info->MR_call_depth;
@@ -344,13 +355,27 @@
return NULL;
}
+ trace_level = entry->MR_sle_module_layout->MR_ml_trace_level;
+ if (trace_level == MR_TRACE_LEVEL_DEEP) {
+ /*
+ ** We ignore events from modules that were not compiled
+ ** with the necessary information. Procedures in those
+ ** modules are effectively assumed correct, so we give
+ ** the user a warning.
+ */
+ MR_edt_compiler_flag_warning = TRUE;
+ return NULL;
+ }
+
#ifdef MR_USE_DECL_STACK_SLOT
if (entry->MR_sle_maybe_decl_debug < 1) {
/*
** If using reserved stack slots, we ignore any event
** for a procedure that does not have a slot reserved.
- ** Such procedures are effectively assumed correct.
+ ** Such procedures are effectively assumed correct, so
+ ** we give the user a warning.
*/
+ MR_edt_compiler_flag_warning = TRUE;
return NULL;
}
#endif /* MR_USE_DECL_STACK_SLOT */
@@ -1141,6 +1166,7 @@
FILE *out;
MR_Unsigned depth_limit;
const char *message;
+ MR_Trace_Level trace_level;
entry = event_info->MR_event_sll->MR_sll_entry;
if (!MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
@@ -1158,6 +1184,17 @@
return FALSE;
}
+ trace_level = entry->MR_sle_module_layout->MR_ml_trace_level;
+ if (trace_level != MR_TRACE_LEVEL_DECL &&
+ trace_level != MR_TRACE_LEVEL_DECL_REP)
+ {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot start declarative debugging, "
+ "because this procedure was not\n"
+ "compiled with trace level `decl'.\n");
+ return FALSE;
+ }
+
#ifdef MR_USE_DECL_STACK_SLOT
if (entry->MR_sle_maybe_decl_debug < 1) {
/* No slots are reserved for declarative debugging */
@@ -1252,6 +1289,11 @@
}
/*
+ ** Clear any warnings.
+ */
+ MR_edt_compiler_flag_warning = FALSE;
+
+ /*
** Start collecting the trace from the desired call, with the
** desired depth bound.
*/
@@ -1298,6 +1340,13 @@
*/
MR_trace_enabled = TRUE;
#endif
+
+ if (MR_edt_compiler_flag_warning) {
+ fprintf(MR_mdb_err, "Warning: some modules were compiled with"
+ " a trace level lower than `decl'.\n"
+ "This may result in calls being omitted from"
+ " the debugging tree.\n");
+ }
MR_TRACE_CALL_MERCURY(
MR_DD_decl_diagnosis(MR_trace_node_store, root, &response,
--------------------------------------------------------------------------
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