updated diff for trace-based primitive debugger
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Feb 4 12:28:12 AEDT 1998
Fergus wrote:
> >+#define saved_reg(save_area, n) \
> >+ LVALUE_COND((n) > MAX_REAL_REG, \
> >+ r(n), \
> >+ save_area[virtual_reg_map[(n) - 1]])
>
> This is buggy, because `r(n)' indirectly refers to `fake_reg'.
Actually, that is not the only bug with references to fake_reg;
the fake_reg array was not being copied to saved_regs.
Here is a diff that fixes this problem. It incorporates Fergus's recent diff
minus the bug.
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
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/references
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_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regs.h,v
retrieving revision 1.4
diff -u -u -r1.4 mercury_regs.h
--- mercury_regs.h 1998/02/03 08:17:20 1.4
+++ mercury_regs.h 1998/02/03 23:45:56
@@ -129,11 +129,12 @@
r(n), \
fake_reg[virtual_reg_map[(n) - 1]])
-/* saved_reg(save_area, n) accesses the given save area instead of fake_reg */
+/* saved_reg(save_area, n) is like virtual_reg, except in that */
+/* it accesses the given save area instead of the machine regs and fake_reg */
#define saved_reg(save_area, n) \
LVALUE_COND((n) > MAX_REAL_REG, \
- r(n), \
+ save_area[(n) + NUM_SPECIAL_REG - 1], \
save_area[virtual_reg_map[(n) - 1]])
/*
@@ -144,6 +145,7 @@
** getting or setting one or two registers?
** Currently they're buggy for n>32 and are not used except for debugging.
*/
+
extern Word get_reg(int);
extern Word set_reg(int, Word);
Index: runtime/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace.c,v
retrieving revision 1.6
diff -u -u -r1.6 mercury_trace.c
--- mercury_trace.c 1998/02/03 08:17:24 1.6
+++ mercury_trace.c 1998/02/04 00:43:26
@@ -77,15 +77,18 @@
MR_NO_INTERACT
} MR_trace_interact;
-void MR_trace_display(MR_trace_interact interact,
- const MR_stack_layout_entry *layout,
- MR_trace_port port, int seqno, int depth, const char *path);
-void MR_trace_browse(int var_count, const MR_stack_layout_vars *var_info);
-void MR_trace_browse_var(char *name, const MR_stack_layout_var *var);
-int MR_trace_get_cmd(void);
-void MR_trace_help(void);
+static void MR_trace_display(MR_trace_interact interact,
+ const MR_stack_layout_entry *layout,
+ MR_trace_port port, int seqno, int depth,
+ const char *path);
+static void MR_trace_browse(int var_count,
+ const MR_stack_layout_vars *var_info);
+static void MR_trace_browse_var(char *name,
+ const MR_stack_layout_var *var);
+static int MR_trace_get_cmd(void);
+static void MR_trace_help(void);
-#define port_is_final(port) (port == MR_PORT_EXIT || port == MR_PORT_FAIL)
+#define MR_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
@@ -109,7 +112,8 @@
break;
case MR_CMD_JUMP:
- if (MR_trace_seqno == seqno && port_is_final(port)) {
+ if (MR_trace_seqno == seqno && MR_port_is_final(port))
+ {
interact = MR_INTERACT;
} else {
interact = MR_NO_INTERACT;
@@ -121,7 +125,8 @@
break;
case MR_CMD_SKIP:
- if (MR_trace_seqno == seqno && port_is_final(port)) {
+ if (MR_trace_seqno == seqno && MR_port_is_final(port))
+ {
MR_trace_display(MR_INTERACT, layout,
port, seqno, depth, path);
}
@@ -146,7 +151,8 @@
}
}
-void MR_trace_display(MR_trace_interact interact,
+static void
+MR_trace_display(MR_trace_interact interact,
const MR_stack_layout_entry *layout,
MR_trace_port port, int seqno, int depth, const char *path)
{
@@ -261,9 +267,9 @@
break;
case 'j':
- if (port_is_final(port)) {
- fprintf(stderr, "mtrace: cannot jump");
- fprintf(stderr, " from this port\n");
+ if (MR_port_is_final(port)) {
+ fprintf(stderr, "mtrace: cannot jump"
+ " from this port\n");
continue;
} else {
MR_trace_cmd = MR_CMD_JUMP;
@@ -282,16 +288,16 @@
layout->MR_sle_out_arg_count,
&layout->MR_sle_out_arg_info);
} else {
- fprintf(stderr, "mtrace: cannot print");
- fprintf(stderr, " from this port\n");
+ fprintf(stderr, "mtrace: cannot print"
+ " from this port\n");
}
continue;
case 's':
- if (port_is_final(port)) {
- fprintf(stderr, "mtrace: cannot skip");
- fprintf(stderr, " from this port\n");
+ if (MR_port_is_final(port)) {
+ fprintf(stderr, "mtrace: cannot skip"
+ " from this port\n");
continue;
} else {
MR_trace_cmd = MR_CMD_SKIP;
@@ -302,8 +308,8 @@
case EOF:
case 'a':
- fprintf(stderr, "mtrace: are you sure");
- fprintf(stderr, " you want to abort? ");
+ fprintf(stderr, "mtrace: are you sure"
+ " you want to abort? ");
if (MR_trace_get_cmd() == 'y') {
MR_trace_cmd = MR_CMD_ABORT;
@@ -321,9 +327,9 @@
}
}
-Word saved_regs[MAX_FAKE_REG];
+static Word MR_saved_regs[MAX_FAKE_REG];
-void
+static void
MR_trace_browse(int var_count, const MR_stack_layout_vars *vars)
{
int i;
@@ -336,14 +342,17 @@
/*
** In the process of browsing, we call Mercury code,
- ** which may clobber the contents of the control registers
- ** and the contents of the gp registers up to r<maxreg>.
+ ** which may clobber the contents of the registers,
+ ** both the control registers and the general purpose registers.
** We must therefore save and restore these.
- ** XXX The value of maxreg ought to be given to us by the compiler
- ** through a parameter to MR_trace; for the time being, we use 10.
+ **
+ ** Some are in real machine registers; others in the fake_reg array.
*/
- save_regs_to_mem(saved_regs);
+ save_regs_to_mem(MR_saved_regs);
+ for (i = NUM_REAL_REGS; i < MAX_FAKE_REG; i++)
+ MR_saved_regs[i] = fake_reg[i];
+
for (i = 0; i < var_count; i++) {
if (vars->MR_slvs_names != NULL &&
vars->MR_slvs_names[i] != NULL)
@@ -354,13 +363,15 @@
MR_trace_browse_var(name, &vars->MR_slvs_pairs[i]);
}
- restore_regs_from_mem(saved_regs);
+ restore_regs_from_mem(MR_saved_regs);
+ for (i = NUM_REAL_REGS; i < MAX_FAKE_REG; i++)
+ fake_reg[i] = MR_saved_regs[i];
}
/* if you want to debug this code, you may want to set this var to 1 */
static int MR_trace_print_locn = 0;
-void
+static void
MR_trace_browse_var(char *name, const MR_stack_layout_var *var)
{
Integer locn;
@@ -385,7 +396,7 @@
case MR_LVAL_TYPE_R:
if (MR_trace_print_locn)
printf("r%d", locn_num);
- value = saved_reg(saved_regs, locn_num);
+ value = saved_reg(MR_saved_regs, locn_num);
print_value = TRUE;
break;
@@ -450,8 +461,9 @@
/*
** XXX It would be nice if we could call an exported C
** function version of the browser predicate, and thus
- ** avoid going through call_engine, but that causes the
- ** Mercury code in the browser to clobber part of the C stack.
+ ** avoid going through call_engine, but for some unknown
+ ** reason, that seems to cause the Mercury code in the
+ ** browser to clobber part of the C stack.
*/
r1 = (Word) var->MR_slv_shape->MR_sls_type;
@@ -462,7 +474,7 @@
printf("\n");
}
-int
+static int
MR_trace_get_cmd(void)
{
int cmd;
@@ -478,15 +490,15 @@
return cmd;
}
-void
+static 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");
- fprintf(stderr, " p: print the variables live at this point.\n");
+ fprintf(stderr, "valid commands are:\n"
+ " a: abort the current execution.\n"
+ " c: continue to end, not printing the trace.\n"
+ " d: continue to end, printing the trace.\n"
+ " n: go to the next trace event.\n"
+ " s: skip the current call, not printing trace.\n"
+ " j: jump to end of current call, printing trace.\n"
+ " p: print the variables live at this point.\n");
}
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/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
Index: tests/misc_tests/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/misc_tests/Mmakefile,v
retrieving revision 1.3
diff -u -u -r1.3 Mmakefile
--- Mmakefile 1998/01/25 20:32:40 1.3
+++ Mmakefile 1998/02/04 00:54:27
@@ -9,14 +9,20 @@
mdemangle_test.out: mdemangle_test.inp
mdemangle < mdemangle_test.inp > mdemangle_test.out 2>&1
+debugger_regs.out: debugger_regs debugger_regs.inp
+ ./debugger_regs debugger_regs.m < debugger_regs.inp \
+ > debugger_regs.out 2>&1
+
debugger_test.out: debugger_test debugger_test.inp
./debugger_test debugger_test.m < debugger_test.inp \
> debugger_test.out 2>&1
#-----------------------------------------------------------------------------#
-PROGS= debugger_test
+PROGS= debugger_regs \
+ debugger_test
+MCFLAGS-debugger_regs = --generate-trace
MCFLAGS-debugger_test = --generate-trace
#-----------------------------------------------------------------------------#
cvs diff: tests/misc_tests/debugger_regs.exp is a new entry, no comparison available
cvs diff: tests/misc_tests/debugger_regs.inp is a new entry, no comparison available
cvs diff: tests/misc_tests/debugger_regs.m is a new entry, no comparison available
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
::::::::::::::
/mount/munkora/staff/zs/mer/ws2/tests/misc_tests/debugger_regs.m
::::::::::::::
% This program tests whether the tracer works for procedures with
% lots of arguments (beyond NUM_REAL_REGS and MAX_REAL_REGS).
% At the moment, MAX_REAL_REGS is 32, so a procedure with 41 args
% is a full test.
:- module debugger_regs.
:- interface.
:- import_module io.
:- pred main(io__state, io__state).
:- mode main(di, uo) is det.
:- implementation.
:- import_module list, int.
main -->
% The purpose of list is to force the tracer to call the Mercury
% code to print a list of integers, when the input script asks
% for the outputs of data to be printed. In the past this was
% sufficed to cause part of the C stack to be overwritten.
% It also tests whether the values of A0 etc that the tracer prints
% are derived from the register contents produced by data,
% or from the register contents left there by the code that
% prints _List.
{ data(_List,
A0, A1, A2, A3, A4, A5, A6, A7, A8, A9,
B0, B1, B2, B3, B4, B5, B6, B7, B8, B9,
C0, C1, C2, C3, C4, C5, C6, C7, C8, C9,
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9) },
io__write_string(A0),
io__write_string(A1),
io__write_string(A2),
io__write_string(A3),
io__write_string(A4),
io__write_string(A5),
io__write_string(A6),
io__write_string(A7),
io__write_string(A8),
io__write_string(A9),
io__write_string("\n"),
io__write_string(B0),
io__write_string(B1),
io__write_string(B2),
io__write_string(B3),
io__write_string(B4),
io__write_string(B5),
io__write_string(B6),
io__write_string(B7),
io__write_string(B8),
io__write_string(B9),
io__write_string("\n"),
io__write_string(C0),
io__write_string(C1),
io__write_string(C2),
io__write_string(C3),
io__write_string(C4),
io__write_string(C5),
io__write_string(C6),
io__write_string(C7),
io__write_string(C8),
io__write_string(C9),
io__write_string("\n"),
io__write_string(D0),
io__write_string(D1),
io__write_string(D2),
io__write_string(D3),
io__write_string(D4),
io__write_string(D5),
io__write_string(D6),
io__write_string(D7),
io__write_string(D8),
io__write_string(D9),
io__write_string("\n").
:- pred data(list(int)::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out,
string::out, string::out, string::out, string::out, string::out) is det.
data([1, 2, 3, 4, 5],
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9",
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9",
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9").
::::::::::::::
/mount/munkora/staff/zs/mer/ws2/tests/misc_tests/debugger_regs.inp
::::::::::::::
p
c
::::::::::::::
/mount/munkora/staff/zs/mer/ws2/tests/misc_tests/debugger_regs.exp
::::::::::::::
1: 1 1 CALL DET debugger_regs:main/2-0
mtrace> 2: 2 2 CALL DET debugger_regs:data/41-0
mtrace> 3: 2 2 EXIT DET debugger_regs:data/41-0
mtrace> mtrace> HeadVar__1 [1, 2, 3, 4, 5]
HeadVar__2 a0
HeadVar__3 a1
HeadVar__4 a2
HeadVar__5 a3
HeadVar__6 a4
HeadVar__7 a5
HeadVar__8 a6
HeadVar__9 a7
HeadVar__10 a8
HeadVar__11 a9
HeadVar__12 b0
HeadVar__13 b1
HeadVar__14 b2
HeadVar__15 b3
HeadVar__16 b4
HeadVar__17 b5
HeadVar__18 b6
HeadVar__19 b7
HeadVar__20 b8
HeadVar__21 b9
HeadVar__22 c0
HeadVar__23 c1
HeadVar__24 c2
HeadVar__25 c3
HeadVar__26 c4
HeadVar__27 c5
HeadVar__28 c6
HeadVar__29 c7
HeadVar__30 c8
HeadVar__31 c9
HeadVar__32 d0
HeadVar__33 d1
HeadVar__34 d2
HeadVar__35 d3
HeadVar__36 d4
HeadVar__37 d5
HeadVar__38 d6
HeadVar__39 d7
HeadVar__40 d8
HeadVar__41 d9
a0a1a2a3a4a5a6a7a8a9
b0b1b2b3b4b5b6b7b8b9
c0c1c2c3c4c5c6c7c8c9
d0d1d2d3d4d5d6d7d8d9
More information about the developers
mailing list