[m-dev.] for review: a "delete" command for the debugger

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Oct 7 13:53:01 AEST 1999


For review by anyone who knows the debugger, maybe Erwan or Mark.

Add a new command to the debugger for deleting (as opposed to disabling)
breakpoints.

doc/user_guide.texi:
	Document the delete command.

trace/mercury_trace_internal.c:
	Implement the delete command, and move all the code that deals with
	breakpoints to trace/mercury_trace_spy.c, with the exception of code
	for user interaction (since this will be different for e.g. the
	external debugger).

	In several places, update the code to reflect the fact that the
	spy points array may now have holes: entries holding deleted spy
	points.

trace/mercury_trace_spy.[ch]:
	Centralize the code for handling breakpoints here, and add a function
	for handling the deletion of a breakpoint.

tests/debugger/breakpoints.{m,inp,exp}:
	A new test case for exercising the new functionality. The code
	is the same as queens.m; it is the script that is different.

tests/debugger/Mmakefile:
	Turn on the new test case.

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 browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.185
diff -u -b -r1.185 user_guide.texi
--- user_guide.texi	1999/09/30 08:55:41	1.185
+++ user_guide.texi	1999/10/07 04:46:31
@@ -1789,6 +1789,13 @@
 @item enable *
 Enables all break points.
 @sp 1
+ at item delete @var{num}
+Deletes the break point with the given number.
+Reports an error if there is no break point with that number.
+ at sp 1
+ at item delete *
+Deletes all break points.
+ at sp 1
 @item modules
 Lists all the debuggable modules
 (i.e. modules that have debugging information).
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
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/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
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/mercury_calls_fortran
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 samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.27
diff -u -b -r1.27 Mmakefile
--- Mmakefile	1999/08/24 09:40:44	1.27
+++ Mmakefile	1999/10/06 12:13:15
@@ -17,6 +17,7 @@
 #-----------------------------------------------------------------------------#
 
 DEBUGGER_PROGS=	\
+	breakpoints			\
 	browser_test			\
 	debugger_regs			\
 	existential_type_classes	\
Index: tests/debugger/breakpoints.exp
===================================================================
RCS file: breakpoints.exp
diff -N breakpoints.exp
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ breakpoints.exp	Thu Oct  7 14:39:35 1999
@@ -0,0 +1,64 @@
+       1:      1  1 CALL pred breakpoints:main/2-0 (cc_multi) 
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break data
+ 0: + stop  interface pred breakpoints:data/1-0 (det)
+mdb> continue
+       2:      2  2 CALL pred breakpoints:data/1-0 (det) 
+mdb> disable 0
+ 0: - stop  interface pred breakpoints:data/1-0 (det)
+mdb> break info
+ 0: - stop  interface pred breakpoints:data/1-0 (det)
+mdb> break qperm
+ 1: + stop  interface pred breakpoints:qperm/2-0 (nondet)
+mdb> break safe
+ 2: + stop  interface pred breakpoints:safe/1-0 (semidet)
+mdb> break -e qperm
+ 3: + stop      entry pred breakpoints:qperm/2-0 (nondet)
+mdb> break -a qperm
+ 4: + stop        all pred breakpoints:qperm/2-0 (nondet)
+mdb> break info
+ 0: - stop  interface pred breakpoints:data/1-0 (det)
+ 1: + stop  interface pred breakpoints:qperm/2-0 (nondet)
+ 2: + stop  interface pred breakpoints:safe/1-0 (semidet)
+ 3: + stop      entry pred breakpoints:qperm/2-0 (nondet)
+ 4: + stop        all pred breakpoints:qperm/2-0 (nondet)
+mdb> delete 0
+ 0: D stop  interface pred breakpoints:data/1-0 (det)
+mdb> break info
+ 1: + stop  interface pred breakpoints:qperm/2-0 (nondet)
+ 2: + stop  interface pred breakpoints:safe/1-0 (semidet)
+ 3: + stop      entry pred breakpoints:qperm/2-0 (nondet)
+ 4: + stop        all pred breakpoints:qperm/2-0 (nondet)
+mdb> disable 3
+ 3: - stop      entry pred breakpoints:qperm/2-0 (nondet)
+mdb> break nodiag
+ 0: + stop  interface pred breakpoints:nodiag/3-0 (semidet)
+mdb> continue
+       5:      4  3 CALL pred breakpoints:qperm/2-0 (nondet) 
+mdb> continue
+       6:      4  3 SWTC pred breakpoints:qperm/2-0 (nondet) s1;
+mdb> finish -N
+      10:      6  4 CALL pred breakpoints:qperm/2-0 (nondet) 
+mdb> finish -n
+      36:      6  4 EXIT pred breakpoints:qperm/2-0 (nondet) 
+mdb> continue
+      37:      4  3 EXIT pred breakpoints:qperm/2-0 (nondet) 
+mdb> continue
+      38:     15  3 CALL pred breakpoints:safe/1-0 (semidet) 
+mdb> finish
+      40:     16  4 CALL pred breakpoints:nodiag/3-0 (semidet) 
+      44:     15  3 FAIL pred breakpoints:safe/1-0 (semidet) 
+mdb> delete *
+ 0: E stop  interface pred breakpoints:nodiag/3-0 (semidet)
+ 1: E stop  interface pred breakpoints:qperm/2-0 (nondet)
+ 2: E stop  interface pred breakpoints:safe/1-0 (semidet)
+ 3: D stop      entry pred breakpoints:qperm/2-0 (nondet)
+ 4: E stop        all pred breakpoints:qperm/2-0 (nondet)
+mdb> break info
+No breakpoints exist.
+mdb> delete *
+No breakpoints exist.
+mdb> continue
+[1, 3, 5, 2, 4]
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: breakpoints.inp
diff -N breakpoints.inp
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ breakpoints.inp	Thu Oct  7 14:39:32 1999
@@ -0,0 +1,26 @@
+echo on
+register --quiet
+break data
+continue
+disable 0
+break info
+break qperm
+break safe
+break -e qperm
+break -a qperm
+break info
+delete 0
+break info
+disable 3
+break nodiag
+continue
+continue
+finish -N
+finish -n
+continue
+continue
+finish
+delete *
+break info
+delete *
+continue
Index: tests/debugger/breakpoints.m
===================================================================
RCS file: breakpoints.m
diff -N breakpoints.m
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ breakpoints.m	Wed Oct  6 22:13:32 1999
@@ -0,0 +1,101 @@
+:- module breakpoints.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state, io__state).
+:- mode main(di, uo) is cc_multi.
+
+:- implementation.
+
+:- import_module list, int.
+
+main -->
+	( { data(Data), queen(Data, Out) } ->
+		print_list(Out)
+	;
+		io__write_string("No solution\n")
+	).
+
+:- pred data(list(int)).
+:- mode data(out) is det.
+
+:- pred queen(list(int), list(int)).
+:- mode queen(in, out) is nondet.
+
+:- pred qperm(list(T), list(T)).
+:- mode qperm(in, out) is nondet.
+
+:- pred qdelete(T, list(T), list(T)).
+:- mode qdelete(out, in, out) is nondet.
+
+:- pred safe(list(int)).
+:- mode safe(in) is semidet.
+
+:- pred nodiag(int, int, list(int)).
+:- mode nodiag(in, in, in) is semidet.
+
+data([1,2,3,4,5]).
+
+queen(Data, Out) :-
+	qperm(Data, Out),
+	safe(Out).
+
+qperm([], []).
+qperm([X|Y], K) :-
+	qdelete(U, [X|Y], Z),
+	K = [U|V],
+	qperm(Z, V).
+
+qdelete(A, [A|L], L).
+qdelete(X, [A|Z], [A|R]) :-
+	qdelete(X, Z, R).
+
+safe([]).
+safe([N|L]) :-
+	nodiag(N, 1, L),
+	safe(L).
+
+nodiag(_, _, []).
+nodiag(B, D, [N|L]) :-
+	NmB is N - B,
+	BmN is B - N,
+	( D = NmB ->
+		fail
+	; D = BmN ->
+		fail
+	;
+		true
+	),
+	D1 is D + 1,
+	nodiag(B, D1, L).
+
+:- pred print_list(list(int), io__state, io__state).
+:- mode print_list(in, di, uo) is det.
+
+print_list(Xs) -->
+	(
+		{ Xs = [] }
+	->
+		io__write_string("[]\n")
+	;
+		io__write_string("["),
+		print_list_2(Xs),
+		io__write_string("]\n")
+	).
+
+:- pred print_list_2(list(int), io__state, io__state).
+:- mode print_list_2(in, di, uo) is det.
+
+print_list_2([]) --> [].
+print_list_2([X|Xs]) --> 
+	io__write_int(X),
+	(
+		{ Xs = [] }
+	->
+		[]
+	;
+		io__write_string(", "),
+		print_list_2(Xs)
+	).
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.51
diff -u -b -r1.51 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/09/20 08:17:06	1.51
+++ mercury_trace_internal.c	1999/10/07 05:07:56
@@ -34,9 +34,6 @@
 #include <ctype.h>
 #include <errno.h>
 
-/* The initial size of the spy points table. */
-#define	MR_INIT_SPY_POINTS	10
-
 /* The initial size of arrays of words. */
 #define	MR_INIT_WORD_COUNT	20
 
@@ -79,15 +76,6 @@
 static	MR_Trace_Print_Level	MR_default_print_level = MR_PRINT_LEVEL_SOME;
 
 /*
-** The table of spy points, with counters saying which is the next free slot
-** and how many slots are allocated.
-*/
-
-static	MR_Spy_Point    	**MR_spy_points;
-static	int			MR_spy_point_next = 0;
-static	int			MR_spy_point_max  = 0;
-
-/*
 ** These variables say (a) whether the printing of event sequences will pause
 ** after each screenful of events, (b) how may events constitute a screenful
 ** (although we count only events, not how many lines they take up), and (c)
@@ -159,10 +147,6 @@
 static	bool	MR_trace_options_confirmed(bool *confirmed, char ***words,
 			int *word_count, const char *cat, const char *item);
 static	void	MR_trace_usage(const char *cat, const char *item);
-static	void	MR_trace_internal_add_spy_point(MR_Spy_When when,
-			MR_Spy_Action action,
-			const MR_Stack_Layout_Entry *entry,
-			const MR_Stack_Layout_Label *label);
 static	void	MR_print_spy_point(int i);
 static	void	MR_trace_do_noop(void);
 
@@ -863,11 +847,22 @@
 		MR_Proc_Spec	spec;
 		MR_Spy_When	when;
 		MR_Spy_Action	action;
+		int		slot;
 
 		if (word_count == 2 && streq(words[1], "info")) {
 			int	i;
+			int	count;
+
+			count = 0;
 			for (i = 0; i < MR_spy_point_next; i++) {
+				if (MR_spy_points[i]->spy_exists) {
 				MR_print_spy_point(i);
+					count++;
+				}
+			}
+
+			if (count == 0) {
+				fprintf(MR_mdb_out, "No breakpoints exist.\n");
 			}
 
 			return KEEP_INTERACTING;
@@ -881,8 +876,9 @@
 			; /* the usage message has already been printed */
 		} else if (word_count == 2 && streq(words[1], "here")) {
 			MR_register_all_modules_and_procs(MR_mdb_out, TRUE);
-			MR_trace_internal_add_spy_point(MR_SPY_SPECIFIC,
-				action, layout->MR_sll_entry, layout);
+			slot = MR_add_spy_point(MR_SPY_SPECIFIC, action,
+					layout->MR_sll_entry, layout);
+			MR_print_spy_point(slot);
 		} else if (word_count == 2 &&
 				MR_parse_proc_spec(words[1], &spec))
 		{
@@ -894,8 +890,9 @@
 					&unique);
 			if (spy_proc != NULL) {
 				if (unique) {
-					MR_trace_internal_add_spy_point(when,
-						action, spy_proc, NULL);
+					MR_add_spy_point(when, action,
+						spy_proc, NULL);
+					MR_print_spy_point(slot);
 				} else {
 					fflush(MR_mdb_out);
 					fprintf(MR_mdb_err,
@@ -917,7 +914,9 @@
 	} else if (streq(words[0], "enable")) {
 		int	n;
 		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
-			if (0 <= n && n < MR_spy_point_next) {
+			if (0 <= n && n < MR_spy_point_next
+					&& MR_spy_points[n]->spy_exists)
+			{
 				MR_spy_points[n]->spy_enabled = TRUE;
 				MR_print_spy_point(n);
 			} else {
@@ -928,14 +927,19 @@
 			}
 		} else if (word_count == 2 && streq(words[1], "*")) {
 			int i;
+			int	count;
+
+			count = 0;
 			for (i = 0; i < MR_spy_point_next; i++) {
+				if (MR_spy_points[i]->spy_exists) {
 				MR_spy_points[i]->spy_enabled = TRUE;
 				MR_print_spy_point(i);
+					count++;
 			}
+			}
 
-			if (MR_spy_point_next == 0) {
-				fprintf(MR_mdb_out,
-					"There are no break points yet.\n");
+			if (count == 0) {
+				fprintf(MR_mdb_err, "No breakpoints exist.\n");
 			}
 		} else {
 			MR_trace_usage("breakpoint", "enable");
@@ -943,7 +947,9 @@
 	} else if (streq(words[0], "disable")) {
 		int	n;
 		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
-			if (0 <= n && n < MR_spy_point_next) {
+			if (0 <= n && n < MR_spy_point_next
+					&& MR_spy_points[n]->spy_exists)
+			{
 				MR_spy_points[n]->spy_enabled = FALSE;
 				MR_print_spy_point(n);
 			} else {
@@ -954,19 +960,58 @@
 			}
 		} else if (word_count == 2 && streq(words[1], "*")) {
 			int i;
+			int	count;
+
+			count = 0;
 			for (i = 0; i < MR_spy_point_next; i++) {
+				if (MR_spy_points[i]->spy_exists) {
 				MR_spy_points[i]->spy_enabled = FALSE;
 				MR_print_spy_point(i);
+					count++;
+				}
 			}
 
-			if (MR_spy_point_next == 0) {
+			if (count == 0) {
 				fflush(MR_mdb_out);
-				fprintf(MR_mdb_err,
-					"There are no break points yet.\n");
+				fprintf(MR_mdb_err, "No breakpoints exist.\n");
 			}
 		} else {
 			MR_trace_usage("breakpoint", "disable");
 		}
+	} else if (streq(words[0], "delete")) {
+		int	n;
+		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
+			if (0 <= n && n < MR_spy_point_next
+					&& MR_spy_points[n]->spy_exists)
+			{
+				MR_delete_spy_point(n);
+				MR_print_spy_point(n);
+			} else {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err,
+					"Break point #%d does not exist.\n",
+					n);
+			}
+		} else if (word_count == 2 && streq(words[1], "*")) {
+			int	i;
+			int	count;
+
+			count = 0;
+			for (i = 0; i < MR_spy_point_next; i++) {
+				if (MR_spy_points[i]->spy_exists) {
+					MR_delete_spy_point(i);
+					MR_print_spy_point(i);
+					count++;
+				}
+			}
+
+			if (count == 0) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "No breakpoints exist.\n");
+			}
+		} else {
+			MR_trace_usage("breakpoint", "delete");
+		}
 	} else if (streq(words[0], "register")) {
 		bool	verbose;
 
@@ -1689,31 +1734,20 @@
 		item, item);
 }
 
-
 static void
-MR_trace_internal_add_spy_point(MR_Spy_When when, MR_Spy_Action action,
-	const MR_Stack_Layout_Entry *entry, const MR_Stack_Layout_Label *label)
-{
-	MR_Spy_Point	*spy_point;
-
-	MR_ensure_room_for_next(MR_spy_point, MR_Spy_Point *,
-		MR_INIT_SPY_POINTS);
-	spy_point = MR_add_spy_point(when, action, entry, label);
-	MR_spy_points[MR_spy_point_next] = spy_point;
-	MR_print_spy_point(MR_spy_point_next);
-	MR_spy_point_next++;
-}
-
-static void
 MR_print_spy_point(int spy_point_num)
 {
+	MR_Spy_Point	*point;
+
+	point = MR_spy_points[spy_point_num];
 	fprintf(MR_mdb_out, "%2d: %1s %-5s %9s ",
 		spy_point_num,
-		MR_spy_points[spy_point_num]->spy_enabled ? "+" : "-",
-		MR_spy_action_string(MR_spy_points[spy_point_num]->spy_action),
-		MR_spy_when_string(MR_spy_points[spy_point_num]->spy_when));
-	MR_print_proc_id(MR_mdb_out, MR_spy_points[spy_point_num]->spy_proc,
-		NULL, NULL, NULL);
+		point->spy_exists ?
+			(point->spy_enabled ? "+" : "-") :
+			(point->spy_enabled ? "E" : "D"),
+		MR_spy_action_string(point->spy_action),
+		MR_spy_when_string(point->spy_when));
+	MR_print_proc_id(MR_mdb_out, point->spy_proc, NULL, NULL, NULL);
 }
 
 /*
@@ -2271,8 +2305,9 @@
 	{ "browsing", "level" },
 	{ "browsing", "current" },
 	{ "breakpoint", "break" },
-	{ "breakpoint", "disable" },
 	{ "breakpoint", "enable" },
+	{ "breakpoint", "disable" },
+	{ "breakpoint", "delete" },
 	{ "breakpoint", "modules" },
 	{ "breakpoint", "procedures" },
 	{ "breakpoint", "register" },
Index: trace/mercury_trace_spy.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_spy.c,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_trace_spy.c
--- mercury_trace_spy.c	1999/02/08 10:51:47	1.3
+++ mercury_trace_spy.c	1999/10/07 05:39:23
@@ -17,6 +17,27 @@
 #include "mercury_trace_spy.h"
 #include "mercury_array_macros.h"
 
+/*
+** The table of spy points, with one entry per existing (or deleted but
+** not yet reused) spy point, with counters saying which is the next
+** free slot and how many slots are allocated.
+*/
+
+static	MR_Spy_Point    	**MR_spy_points;
+static	int			MR_spy_point_next = 0;
+static	int			MR_spy_point_max  = 0;
+
+/* The initial size of the spy points table. */
+#define	MR_INIT_SPY_POINTS	10
+
+/*
+** The table of spied on procedures, with one entry per procedure that
+** has ever been spied on, giving the possibly empty list of spy points
+** (enabled or disabled but not deleted) that refer to that procedure,
+** with counters saying which is the next free slot and how many slots
+** are allocated.
+*/
+
 typedef struct {
 	const MR_Stack_Layout_Entry	*spy_proc;
 	MR_Spy_Point			*spy_points;
@@ -26,8 +47,11 @@
 static	int		MR_spied_proc_next = 0;
 static	int		MR_spied_proc_max = 0;
 
-#define	INIT_SPY_TABLE_SIZE	10
+/* The initial size of the spied procs table. */
+#define	MR_INIT_SPIED_PROCS	10
 
+/**************************************************************************/
+
 static	int	MR_compare_addr(const void *address1, const void *address2);
 static	int	MR_search_spy_table_for_proc(const MR_Stack_Layout_Entry
 			*entry);
@@ -38,6 +62,7 @@
 ** greater than the second.  Suitable for use with MR_bsearch() and
 ** MR_prepare_insert_into_sorted().
 */
+
 static int
 MR_compare_addr(const void *address1, const void *address2)
 {
@@ -60,6 +85,7 @@
 ** Return the index of the entry in MR_spied_procs whose spy_proc field
 ** is entry, or a negative number if absent.
 */
+
 static int
 MR_search_spy_table_for_proc(const MR_Stack_Layout_Entry *entry)
 {
@@ -148,34 +174,84 @@
 	}
 }
 
-MR_Spy_Point *
+int
 MR_add_spy_point(MR_Spy_When when, MR_Spy_Action action,
 	const MR_Stack_Layout_Entry *entry, const MR_Stack_Layout_Label *label)
 {
 	MR_Spy_Point	*point;
-	int		slot;
+	int		point_slot;
+	int		proc_slot;
+	int		i;
 	bool		found;
 
-	slot = MR_search_spy_table_for_proc(entry);
-	if (slot < 0) {
+	proc_slot = MR_search_spy_table_for_proc(entry);
+	if (proc_slot < 0) {
 		MR_ensure_room_for_next(MR_spied_proc, MR_Spied_Proc,
-			INIT_SPY_TABLE_SIZE);
+			MR_INIT_SPIED_PROCS);
 		MR_prepare_insert_into_sorted(MR_spied_procs,
-			MR_spied_proc_next, slot,
-			MR_compare_addr(MR_spied_procs[slot].spy_proc, entry));
-		MR_spied_procs[slot].spy_proc = entry;
-		MR_spied_procs[slot].spy_points = NULL;
+			MR_spied_proc_next, proc_slot,
+			MR_compare_addr(MR_spied_procs[proc_slot].spy_proc,
+				entry));
+		MR_spied_procs[proc_slot].spy_proc = entry;
+		MR_spied_procs[proc_slot].spy_points = NULL;
 	}
 
 	/* Insert the spy point at the head of the list for the proc. */
 	point = checked_malloc(sizeof(MR_Spy_Point));
 	point->spy_when    = when;
+	point->spy_exists  = TRUE;
 	point->spy_enabled = TRUE;
 	point->spy_action  = action;
 	point->spy_proc    = entry;
 	point->spy_label   = label;
-	point->spy_next    = MR_spied_procs[slot].spy_points;
-	MR_spied_procs[slot].spy_points = point;
+	point->spy_next    = MR_spied_procs[proc_slot].spy_points;
+	MR_spied_procs[proc_slot].spy_points = point;
+
+	for (i = 0; i < MR_spy_point_next; i++) {
+		if (! MR_spy_points[i]->spy_exists) {
+			MR_spy_points[i] = point;
+			return i;
+		}
+	}
+
+	MR_ensure_room_for_next(MR_spy_point, MR_Spy_Point *,
+		MR_INIT_SPY_POINTS);
+	point_slot = MR_spy_point_next;
+	MR_spy_points[point_slot] = point;
+	MR_spy_point_next++;
+
+	return point_slot;
+}
+
+void
+MR_delete_spy_point(int point_table_slot)
+{
+	MR_Spy_Point	*point;
+	MR_Spy_Point	**cur_addr;
+	MR_Spy_Point	*cur;
+	int		proc_table_slot;
+
+	point = MR_spy_points[point_table_slot];
+
+	/* this effectively remove the point from the spypoint table */
+	point->spy_exists = FALSE;
+
+	/* now remove the point from the spied proc table list for its proc */
+	proc_table_slot = MR_search_spy_table_for_proc(point->spy_proc);
+	if (proc_table_slot < 0) {
+		fatal_error("deleted spy point was not indexed by proc addr");
+	}
+
+	cur_addr = &MR_spied_procs[proc_table_slot].spy_points;
+	cur = MR_spied_procs[proc_table_slot].spy_points;
+	while (cur != NULL && cur != point) {
+		cur_addr = &cur->spy_next;
+		cur = cur->spy_next;
+	}
+
+	if (cur == NULL) {
+		fatal_error("deleted spy point was not on proc index list");
+	}
 
-	return point;
+	*cur_addr = point->spy_next;
 }
Index: trace/mercury_trace_spy.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_spy.h,v
retrieving revision 1.1
diff -u -b -r1.1 mercury_trace_spy.h
--- mercury_trace_spy.h	1998/10/16 06:20:21	1.1
+++ mercury_trace_spy.h	1999/10/07 05:03:08
@@ -35,8 +35,9 @@
 typedef struct MR_Spy_Point_Struct MR_Spy_Point;
 
 struct MR_Spy_Point_Struct {
-	MR_Spy_When			spy_when;
+	bool				spy_exists; /* FALSE if deleted */
 	bool				spy_enabled;
+	MR_Spy_When			spy_when;
 	MR_Spy_Action			spy_action;
 	const MR_Stack_Layout_Entry	*spy_proc;
 	const MR_Stack_Layout_Label	*spy_label; /* if MR_SPY_SPECIFIC */
@@ -44,6 +45,15 @@
 };
 
 /*
+** The table of spy points, with counters saying which is the next free slot
+** and how many slots are allocated.
+*/
+
+extern	MR_Spy_Point    **MR_spy_points;
+extern	int		MR_spy_point_next;
+extern	int		MR_spy_point_max;
+
+/*
 ** Check whether the event described by the given label layout and port
 ** matches any spy points. If yes, return TRUE and set *action to say what
 ** action should be executed for the spy point.
@@ -57,9 +67,15 @@
 ** Add a new spy point to the table.
 */
 
-extern	MR_Spy_Point	*MR_add_spy_point(MR_Spy_When when,
+extern	int		MR_add_spy_point(MR_Spy_When when,
 				MR_Spy_Action action,
 				const MR_Stack_Layout_Entry *entry,
 				const MR_Stack_Layout_Label *label);
+
+/*
+** Delete a spy point from the table.
+*/
+
+extern	void		MR_delete_spy_point(int point_table_slot);
 
 #endif	/* not MERCURY_TRACE_SPY_H */
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
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