for review: a primitive four-port debugger
Zoltan Somogyi
zs at cs.mu.oz.au
Wed Dec 24 12:32:35 AEDT 1997
compiler/mercury_trace.[ch]:
Implement a *very* rudimentary four-port debugger (actually with seven
ports) using the trace function as a hook. Only predicate names, depths
and call numbers are available as yet, not the values of any arguments
or variables. The commands are:
a: abort the current execution.
c: continue to end, not printing the trace.
d: continue to end, printing the trace.
n: go to the next trace event.
s: skip the current call, not printing trace.
j: jump to end of current call, printing trace.
Merge MR_trace and MR_trace_path into one function, with the path
argument meaningful only for some ports. This reduces code duplication,
which previously was not significant, but would be now.
compiler/trace.m:
Emit code that conforms to the new interface in the runtime.
Zoltan.
cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing bytecode/test
cvs diff: Diffing compiler
Index: compiler/trace.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trace.m,v
retrieving revision 1.2
diff -u -u -r1.2 trace.m
--- trace.m 1997/10/13 08:09:57 1.2
+++ trace.m 1997/12/23 08:47:35
@@ -103,38 +103,29 @@
predicate_arity(ModuleInfo, PredId, Arity),
string__int_to_string(Arity, ArityStr),
Quote = """",
+ Comma = ", ",
trace__port_to_string(Port, PortStr),
trace__code_model_to_string(CodeModel, CodeModelStr),
proc_id_to_int(ProcId, ProcInt),
ModeNum is ProcInt mod 10000,
string__int_to_string(ModeNum, ModeNumStr),
( trace__port_path(Port, Path) ->
- trace__path_to_string(Path, PathStr),
- string__append_list([
- "MR_trace_path(",
- PortStr, ", ",
- CodeModelStr, ", ",
- CallNumStr, ", ",
- CallDepthStr, ", ",
- Quote, ModuleName, Quote, ", ",
- Quote, PredName, Quote, ", ",
- ArityStr, ", ",
- ModeNumStr, ", ",
- Quote, PathStr, Quote, ");\n"],
- TraceStmt)
+ trace__path_to_string(Path, PathStr)
;
- string__append_list([
- "MR_trace(",
- PortStr, ", ",
- CodeModelStr, ", ",
- CallNumStr, ", ",
- CallDepthStr, ", ",
- Quote, ModuleName, Quote, ", ",
- Quote, PredName, Quote, ", ",
- ArityStr, ", ",
- ModeNumStr, ");\n"],
- TraceStmt)
+ PathStr = ""
),
+ string__append_list([
+ "MR_trace(",
+ PortStr, Comma,
+ CodeModelStr, Comma,
+ CallNumStr, Comma,
+ CallDepthStr, Comma,
+ Quote, ModuleName, Quote, Comma,
+ Quote, PredName, Quote, Comma,
+ ArityStr, Comma,
+ ModeNumStr, Comma,
+ Quote, PathStr, Quote, ");\n"],
+ TraceStmt),
TraceCode = node([c_code(TraceStmt) - ""])
}.
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace.c,v
retrieving revision 1.3
diff -u -u -r1.3 mercury_trace.c
--- mercury_trace.c 1997/11/23 07:21:40 1.3
+++ mercury_trace.c 1997/12/23 09:39:19
@@ -10,73 +10,144 @@
** For the general basis of trace analysis systems, see the paper
** "Opium: An extendable trace analyser for Prolog" by Mireille Ducasse,
** available from http://www.irisa.fr/lande/ducasse.
+**
+** Main author: Erwan Jahier.
+** Significant adaptations by Zoltan Somogyi.
*/
#include "mercury_imp.h"
#include "mercury_trace.h"
#include <stdio.h>
+/*
+** MR_trace_call_seqno counts distinct calls. The prologue of every
+** procedure assigns the current value of this counter as the sequence number
+** of that invocation and increments the counter. This is the only way that
+** MR_trace_call_seqno is modified.
+**
+** MR_trace_call_depth records the current depth of the call tree. The prologue
+** of every procedure assigns the current value of this variable plus one
+** as the depth of that invocation. Just before making a call, the caller
+** will set MR_trace_call_depth to its own remembered depth value. These
+** are the only ways in which MR_trace_call_seqno is modified.
+**
+** Although neither MR_trace_call_seqno nor MR_trace_call_depth are used
+** directly in this module, the seqno and depth arguments of MR_trace
+** always derive their values from the saved values of these two global
+** variables.
+*/
+
int MR_trace_call_seqno = 0;
int MR_trace_call_depth = 0;
+/*
+** MR_trace_event_number is a simple counter of events; currently we only
+** use it for display.
+*/
+
+static int MR_trace_event_number = 0;
+
+/*
+** MR_trace_cmd and MR_trace_seqno are globals variables that we use
+** to manage an interface between the tracer and the user.
+**
+** MR_trace_cmd says what mode the tracer is in, i.e. what the last
+** trace command was.
+**
+** MR_trace_seqno is meaningful only when MR_trace_cmd is MR_SKIP or MR_JUMP.
+** In those cases, it holds the sequence number of the call at whose exit
+** control should be given back to the user.
+*/
+
+typedef enum {
+ MR_CMD_ABORT, /* a: abort the current execution */
+ MR_CMD_CONT, /* c: continue to end, not printing the trace */
+ MR_CMD_DUMP, /* d: continue to end, printing the trace */
+ MR_CMD_NEXT, /* n: go to the next trace event */
+ MR_CMD_SKIP, /* s: skip the current call, not printing trace */
+ MR_CMD_JUMP /* j: jump to end of current call, printing trace */
+} MR_trace_cmd_type;
+
+static MR_trace_cmd_type MR_trace_cmd = MR_CMD_NEXT;
+static int MR_trace_seqno = 0;
+
+void MR_trace_display(MR_trace_port port, MR_trace_code_model model, int seqno,
+ int depth, const char *modulename, const char *predname,
+ int arity, int modenum, const char *path);
+void MR_trace_interaction(MR_trace_port port, int seqno);
+void MR_trace_help(void);
+
+#define port_is_final(port) (port == MR_PORT_EXIT || port == MR_PORT_FAIL)
+
+/*
+** This function is called from compiled code whenever an event to be traced
+** occurs.
+*/
+
void
MR_trace(MR_trace_port port, MR_trace_code_model model, int seqno, int depth,
- const char *modulename, const char *predname, int arity, int modenum)
+ const char *modulename, const char *predname, int arity, int modenum,
+ const char *path)
{
- int i;
+ MR_trace_event_number++;
+ switch (MR_trace_cmd)
+ {
+ case MR_CMD_NEXT:
+ MR_trace_display(port, model, seqno, depth, modulename,
+ predname, arity, modenum, path);
+ MR_trace_interaction(port, seqno);
+ break;
- fprintf(stderr, "%4d %2d ", seqno, depth);
+ case MR_CMD_JUMP:
+ MR_trace_display(port, model, seqno, depth,
+ modulename, predname, arity,
+ modenum, path);
- for (i = 0; i < depth; i++)
- {
- putc(' ', stderr);
- }
+ if (MR_trace_seqno == seqno && port_is_final(port))
+ {
+ MR_trace_interaction(port, seqno);
+ }
- switch (port)
- {
- case MR_PORT_CALL:
- fprintf(stderr, "CALL ");
break;
- case MR_PORT_EXIT:
- fprintf(stderr, "EXIT ");
- break;
+ case MR_CMD_SKIP:
+ if (MR_trace_seqno == seqno && port_is_final(port))
+ {
+ MR_trace_display(port, model, seqno, depth,
+ modulename, predname, arity,
+ modenum, path);
+
+ MR_trace_interaction(port, seqno);
+ }
- case MR_PORT_FAIL:
- fprintf(stderr, "FAIL ");
break;
- default:
- fatal_error("MR_trace called with inappropriate port");
- }
+ case MR_CMD_CONT:
+ break;
- switch (model)
- {
- case MR_MODEL_DET:
- fprintf(stderr, "DET ");
+ case MR_CMD_DUMP:
+ MR_trace_display(port, model, seqno, depth,
+ modulename, predname, arity,
+ modenum, path);
break;
- case MR_MODEL_SEMI:
- fprintf(stderr, "SEMI ");
+ case MR_CMD_ABORT:
+ fatal_error("aborting the execution on user request");
break;
- case MR_MODEL_NON:
- fprintf(stderr, "NON ");
+ default:
+ fatal_error("MR_trace called with inappropriate port");
break;
}
-
- fprintf(stderr, "%s:%s/%d-%d\n", modulename, predname, arity, modenum);
}
-void
-MR_trace_path(MR_trace_port port, MR_trace_code_model model,
- int seqno, int depth,
- const char *modulename, const char *predname, int arity, int modenum,
- const char *path)
+void MR_trace_display(MR_trace_port port, MR_trace_code_model model, int seqno,
+ int depth, const char *modulename, const char *predname,
+ int arity, int modenum, const char *path)
{
int i;
- fprintf(stderr, "%4d %2d ", seqno, depth);
+ fprintf(stderr, "%8d: %6d %2d ", MR_trace_event_number, seqno, depth);
for (i = 0; i < depth; i++)
{
@@ -85,6 +156,18 @@
switch (port)
{
+ case MR_PORT_CALL:
+ fprintf(stderr, "CALL ");
+ break;
+
+ case MR_PORT_EXIT:
+ fprintf(stderr, "EXIT ");
+ break;
+
+ case MR_PORT_FAIL:
+ fprintf(stderr, "FAIL ");
+ break;
+
case MR_PORT_THEN:
fprintf(stderr, "THEN ");
break;
@@ -102,7 +185,7 @@
break;
default:
- fatal_error("MR_trace_path called with inappropriate port");
+ fatal_error("MR_trace_display called with inappropriate port");
}
switch (model)
@@ -122,4 +205,84 @@
fprintf(stderr, "%s:%s/%d-%d %s\n",
modulename, predname, arity, modenum, path);
+}
+
+void
+MR_trace_interaction(MR_trace_port port, int seqno)
+{
+ int cmd;
+ int c;
+
+ fprintf(stderr, "trace command [a|c|d|j|n|s] ");
+
+ cmd = getchar(); /* read the trace command */
+
+ /* skip the rest of the line */
+ c = cmd;
+ while (c != EOF && c != '\n')
+ c = getchar();
+
+ switch (cmd)
+ {
+ case 'n':
+ case '\n':
+ MR_trace_cmd = MR_CMD_NEXT;
+ break;
+
+ case 'c':
+ MR_trace_cmd = MR_CMD_CONT;
+ break;
+
+ case 'd':
+ MR_trace_cmd = MR_CMD_DUMP;
+ break;
+
+ case 'j':
+ if (port_is_final(port))
+ {
+ fprintf(stderr, "cannot jump from this port\n");
+ MR_trace_interaction(port, seqno);
+ }
+ else
+ {
+ MR_trace_cmd = MR_CMD_JUMP;
+ MR_trace_seqno = seqno;
+ }
+
+ break;
+
+ case 's':
+ if (port_is_final(port))
+ {
+ fprintf(stderr, "cannot skip from this port\n");
+ MR_trace_interaction(port, seqno);
+ }
+ else
+ {
+ MR_trace_cmd = MR_CMD_SKIP;
+ MR_trace_seqno = seqno;
+ }
+
+ break;
+
+ case 'a':
+ MR_trace_cmd = MR_CMD_ABORT;
+ break;
+
+ default:
+ MR_trace_help();
+ MR_trace_interaction(port, seqno);
+ }
+}
+
+void
+MR_trace_help(void)
+{
+ fprintf(stderr, "valid commands are:\n");
+ fprintf(stderr, " a: abort the current execution.\n");
+ fprintf(stderr, " c: continue to end, not printing the trace.\n");
+ fprintf(stderr, " d: continue to end, printing the trace.\n");
+ fprintf(stderr, " n: go to the next trace event.\n");
+ fprintf(stderr, " s: skip the current call, not printing trace.\n");
+ fprintf(stderr, " j: jump to end of current call, printing trace.\n");
}
Index: runtime/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace.h,v
retrieving revision 1.3
diff -u -u -r1.3 mercury_trace.h
--- mercury_trace.h 1997/10/13 08:10:49 1.3
+++ mercury_trace.h 1997/11/27 04:47:23
@@ -40,16 +40,6 @@
const char *, /* module name */
const char *, /* predicate name */
int, /* predicate arity */
- int); /* mode number within predicate */
-
-extern void MR_trace_path(
- MR_trace_port,
- MR_trace_code_model,
- int, /* call sequence number */
- int, /* call depth */
- const char *, /* module name */
- const char *, /* predicate name */
- int, /* predicate arity */
int, /* mode number within predicate */
const char *); /* path to event goal within procedure */
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
More information about the developers
mailing list