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