For review: handling one by one variable retrieval within the external debugger

Erwan Jahier Erwan.Jahier at irisa.fr
Tue Jul 28 18:20:06 AEST 1998


Estimated hours taken: 50

This change implements one by one retrieval of live variables within the
external debugger. To do so, we basically need two new primitives at the
debugger user disposal: 'current_live_var_names/0' to retrieve the live
variables names and their types (to let user chose which variable he
wants to retrieve) and 'current_nth_var/1' to retrieve the live
variable.

library/debugger_interface.m: 
	Implement new predicates that are called in mercury_trace_external.c: 
	output_current_nth_var/5 send to the debugger process the requested
	live variable.

	output_current_live_var_names/6 send to the debugger process the 
	list of the internal names of the currently live variables and the
	list of their corresponding types.

	get_var_number/1 returns the integer 'n' where its argument is of the
	form 'current_nth_var(n)'.

library/std_util.m:
	Export type_name/1; is is needed to convert type_info into string in 
	mercury_trace_external.c.

runtime/mercury_init.h:
	Add prototype declarations for the new procedures.

runtime/mercury_trace_external.c:
	MR_output_current_nth_var() calls the predicate
output_current_nth_var/5
	defined in library/debugger_interface.m.

	MR_output_current_live_var_names() calls the predicate 
	output_current_live_var_names/6 defined in
library/debugger_interface.m.

	MR_trace_make_type_list() returns the list of the types of the live
	variables.

	MR_trace_make_nth_var() returns the requested live variables.

	MR_get_var_number() calls the predicate get_var_number/1 defined in 
	library/debugger_interface.m.
 
runtime/mercury_trace_util.c:
runtime/mercury_trace_util.h:
	Define a new function MR_trace_get_type() that retrieves the 
	type_info of a live variable. It is the same function as 
	MR_trace_get_type_and_value() except it does not retrieves the value.

runtime/mercury_wrapper.h:
	Declare prototypes of new procedures.

util/mkinit.c:
	Handling new procedures.

Index: debugger_interface.m
===================================================================
RCS file:
/home/mercury1/repository/mercury/library/debugger_interface.m,v
retrieving revision 1.4
diff -u -r1.4 debugger_interface.m
--- debugger_interface.m	1998/07/27 15:25:29	1.4
+++ debugger_interface.m	1998/07/28 07:50:21
@@ -100,6 +100,13 @@
  				% XXX should provide a way of getting
 				% just part of the arguments
  				% (to reduce unnecessary socket traffic)
+		% A `current_live_var_names' request instructs the debuggee to
+		% retrieve the list of internal names of the currently 
+		% live variables and a list of their corresponding types.
+	;	current_live_var_names
+		% A 'current_nth_var' request instructs the debuggee to 
+		% retrieve the specified live variable.
+	;	current_nth_var(int)
 	;	abort_prog
 			% just abort the program
 	;	no_trace
@@ -153,6 +160,11 @@
  		)
 	% responses to current_vars
 	;	current_vars(list(univ), list(string))
+	% reponse to current_nth_var
+	;	current_nth_var(univ)
+	% responses to current_live_var_names
+	;	current_live_var_names(list(string), list(string))
+	% response sent when the last event is reached
 	;	last_event
 	% responses to abort_prog or no_trace
 	;	ok
@@ -190,7 +202,7 @@
 	io__flush_output(OutputStream).
 
 % output_current_vars "ML_DI_output_current_vars":
-%	send to the debugger the list of the live arguments of the current
event.
+%	send to the debugger the list of the live variables of the current
event.
 
 :- pragma export(output_current_vars(in, in, in, di, uo),
"ML_DI_output_current_vars").
 			
@@ -206,6 +218,58 @@
 	io__print(OutputStream, ".\n"),
 	io__flush_output(OutputStream).
 
+% output_current_nth_var "ML_DI_output_current_nth_var":
+%	send to the debugger the requested live variable of the current
event.
+
+:- pragma export(output_current_nth_var(in, in, di, uo),
"ML_DI_output_current_nth_var").
+			
+:- pred output_current_nth_var(univ, io__output_stream, io__state,
io__state).
+:- mode output_current_nth_var(in, in, di, uo) is det.
+
+
+output_current_nth_var(Var, OutputStream) -->
+		
+	{ CurrentTraceInfo = current_nth_var(Var) },
+	io__write(OutputStream, CurrentTraceInfo),
+	io__print(OutputStream, ".\n"),
+	io__flush_output(OutputStream).
+
+
+:- pragma export(output_current_live_var_names(in, in, in, di, uo), 
+	"ML_DI_output_current_live_var_names").
+			
+:- pred output_current_live_var_names(list(string), list(string),
+	io__output_stream, io__state, io__state).
+:- mode output_current_live_var_names(in, in, in, di, uo) is det.
+
+
+output_current_live_var_names(LiveVarNameList, LiveVarTypeList, 
+	OutputStream) -->
+		
+	{ CurrentTraceInfo = current_live_var_names(
+				LiveVarNameList, LiveVarTypeList) },
+	io__write(OutputStream, CurrentTraceInfo),
+	io__print(OutputStream, ".\n"),
+	io__flush_output(OutputStream).
+
+%-----------------------------------------------------------------------------%
+
+:- pragma export(get_var_number(in) = out, "ML_DI_get_var_number").
+			
+:- func get_var_number(debugger_request) = int.
+:- mode get_var_number(in) = out is det.
+	% This function is intended to retrieve the integer in 
+	% "current_nth_var(int)" requests. 
+
+get_var_number(DebuggerRequest) = VarNumber :-
+	(
+		DebuggerRequest = current_nth_var(Var)
+	->
+		Var = VarNumber
+	;
+		error("get_var_number: not a current_nth_var request")
+	).
+

%-----------------------------------------------------------------------------%
 
 :- pragma export(found_match(in, in, in, in, in, in, in, in, in, in,
@@ -307,6 +371,8 @@
 classify_request(no_trace, 4).
 classify_request(abort_prog, 5).
 classify_request(error(_), 6).
+classify_request(current_live_var_names, 7).
+classify_request(current_nth_var(_), 8).
 
 

%-----------------------------------------------------------------------------%


Index: std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.124
diff -u -r1.124 std_util.m
--- std_util.m	1998/07/22 07:42:06	1.124
+++ std_util.m	1998/07/28 07:35:18
@@ -1319,6 +1319,8 @@
 }
 ").
 
+:- pragma export(type_name(in) = out, "ML_type_name").
+
 type_name(Type) = TypeName :-
 	type_ctor_and_args(Type, TypeCtor, ArgTypes),
 	type_ctor_name_and_arity(TypeCtor, ModuleName, Name, Arity),

Index: mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_init.h
--- mercury_init.h	1998/07/27 15:25:35	1.4
+++ mercury_init.h	1998/07/28 07:34:21
@@ -101,13 +101,22 @@
 /* in library/debugger_interface.m */
 void	ML_DI_output_current_vars(Word, Word, Word);
 		/* normally ML_DI_output_current_vars (output_current_vars/4) */
+void	ML_DI_output_current_nth_var(Word, Word);
+		/* normally ML_DI_output_current_nth_var (output_current_nth_var/3)
*/
+void	ML_DI_output_current_live_var_names(Word, Word, Word);
+		/* normally ML_DI_output_current_live_var_names 
+					   (output_current_live_var_names/5) */
 void	ML_DI_output_current_slots(Integer, Integer, Integer, Word,
String,
 		String, Integer, Integer, Integer, String, Word);
 		/* normally ML_DI_output_current_slots (output_current_slots/13) */
 bool	ML_DI_found_match(Integer, Integer, Integer, Word, String, String,
 		Integer, Integer, Integer, Word, String, Word);
 		/* normally ML_DI_found_match (found_match/12) */
+int	ML_DI_get_var_number(Word);
 void	ML_DI_read_request_from_socket(Word, Word *, Integer *);
+
+/* in library/std_util.m  */
+String	ML_type_name(Word);
 
 
 #endif /* not MERCURY_INIT_H */

Index: mercury_trace_external.c
===================================================================
RCS file:
/home/mercury1/repository/mercury/runtime/mercury_trace_external.c,v
retrieving revision 1.6
diff -u -r1.6 mercury_trace_external.c
--- mercury_trace_external.c	1998/07/27 15:25:33	1.6
+++ mercury_trace_external.c	1998/07/28 07:30:12
@@ -50,6 +50,10 @@
 	MR_REQUEST_NO_TRACE      = 4, /* continue to end, not tracing	      */
 	MR_REQUEST_ABORT_PROG    = 5, /* abort the current execution	      */
 	MR_REQUEST_ERROR         = 6, /* something went wrong                
*/
+	MR_REQUEST_CURRENT_LIVE_VAR_NAMES  
+				 = 7, /* report data for current_live_var_names query */
+	MR_REQUEST_CURRENT_NTH_VAR 
+				 = 8  /* report data for current_nth_var query */
 
 } MR_debugger_request_type;
 
@@ -69,7 +73,14 @@
 			MR_trace_port port, Unsigned seqno, Unsigned depth, 
 			const char *path);
 static void	MR_output_current_vars(Word var_list, Word string_list);
+static void	MR_output_current_nth_var(Word var);
+static void	MR_output_current_live_var_names(Word var_names_list, 
+						 Word type_list);
 static Word	MR_trace_make_var_names_list(const MR_Stack_Layout_Label
*layout);
+static Word	MR_trace_make_type_list(const MR_Stack_Layout_Label
*layout);
+static Word	MR_trace_make_nth_var(const MR_Stack_Layout_Label *layout, 
+				      Word debugger_request);
+static int	MR_get_var_number(Word debugger_request);
 
 #if 0
 This pseudocode should go in the debugger process:
@@ -348,6 +359,17 @@
 			        searching = TRUE;
 				return;
 
+			case MR_REQUEST_CURRENT_LIVE_VAR_NAMES:
+				if (MR_debug_socket) {
+					fprintf(stderr, "\nMercury runtime: "
+						"MR_REQUEST_CURRENT_LIVE_VAR_NAMES\n");
+				}
+				var_names_list = MR_trace_make_var_names_list(layout);
+				type_list = MR_trace_make_type_list(layout);
+				MR_output_current_live_var_names(var_names_list,
+								 type_list);
+				break;
+
 			case MR_REQUEST_CURRENT_VARS:
 				if (MR_debug_socket) {
 					fprintf(stderr, "\nMercury runtime: "
@@ -358,6 +380,15 @@
 				MR_output_current_vars(var_list, var_names_list);
 				break;
 
+			case MR_REQUEST_CURRENT_NTH_VAR:
+				if (MR_debug_socket) {
+					fprintf(stderr, "\nMercury runtime: "
+						"REQUEST_NTH_CURRENT_VAR\n");
+				}
+				var = MR_trace_make_nth_var(layout, 
+							    debugger_request);
+				MR_output_current_nth_var(var);
+				break;			
 			case MR_REQUEST_CURRENT_SLOTS:
 				if (MR_debug_socket) {
 					fprintf(stderr, "\nMercury runtime: "
@@ -407,6 +438,22 @@
 		(Word) &MR_debugger_socket_out);
 }
 
+static void
+MR_output_current_nth_var(Word var)
+{
+	MR_DI_output_current_nth_var(
+		var,
+		(Word) &MR_debugger_socket_out);
+}
+
+static void
+MR_output_current_live_var_names(Word var_names_list, Word type_list)
+{
+	MR_DI_output_current_live_var_names(
+		var_names_list,
+		type_list,
+		(Word) &MR_debugger_socket_out);
+}
 
 static void
 MR_read_request_from_socket(
@@ -456,7 +503,6 @@
 }
 
 
-
 /*
 ** This function returns the list of the internal names of currently
live
 ** variables.
@@ -490,4 +536,109 @@
 }
 
 
+/*
+** This function returns the list of types of currently live variables.
+*/
+
+static Word
+MR_trace_make_type_list(const MR_Stack_Layout_Label *layout)
+{
+	int 				var_count;
+	const MR_Stack_Layout_Vars 	*vars;
+	int				i;
+	const char			*name;
+	MR_Stack_Layout_Var*		var;
+	Word				type_info;
+	String		      		type_info_string;
+
+	Word				type_list;
+
+	var_count = layout->MR_sll_var_count;
+	vars = &layout->MR_sll_var_info;
+
+	restore_transient_registers();
+	type_list = list_empty();
+	save_transient_registers();
+	for (i = var_count - 1; i >= 0; i--) {
+
+		name = MR_name_if_present(vars, i);
+		var = &vars->MR_slvs_pairs[i];
+
+		if ((strncmp(name, "TypeInfo", 8) == 0)
+		|| (strncmp(name, "ModuleInfo", 10) == 0)
+		|| (strncmp(name, "HLDS", 4) == 0)
+		|| !MR_trace_get_type(var, NULL, &type_info))
+		{
+			continue;
+		}
+
+		restore_transient_registers();
+		type_info_string = MR_type_name(type_info);
+		type_list = list_cons(type_info_string, type_list);
+		save_transient_registers();
+	}
+
+	return type_list;
+}
+
+
+/*
+** This function returns the requested live variable.
+*/
+
+static Word
+MR_trace_make_nth_var(const MR_Stack_Layout_Label *layout, Word
debugger_request)
+{
+	int 				var_number;
+	const MR_Stack_Layout_Vars 	*vars;
+	const char			*name;
+	MR_Stack_Layout_Var*		var;
+	int				i;
+	Word				value;
+	Word				type_info;
+
+	Word				univ;
+
+	var_number = MR_get_var_number(debugger_request);
+		/* debugger_request should be of the form:
current_nth_var(var_number) */
+	vars = &layout->MR_sll_var_info;
+	name = MR_name_if_present(vars, var_number);
+	var = &vars->MR_slvs_pairs[var_number];
+
+	restore_transient_registers();
+	incr_hp(univ, 2);
+
+	if ((strncmp(name, "TypeInfo", 8) == 0)
+	    || (strncmp(name, "ModuleInfo", 10) == 0)
+	    || (strncmp(name, "HLDS", 4) == 0)
+	    || !MR_trace_get_type_and_value(var, NULL, &type_info, &value))
+	  {
+	    field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
+	    field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
+	  } else {
+	    field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
+	    field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
+	  }
+
+	save_transient_registers();
+
+	return univ;
+}
+
+
+/*
+** This function is called only when debugger_request =
current_nth_var(n).
+** It returns the integer 'n'.
+*/
+
+/* XXX note for the reviewer: is there a way to do that in C ? */
+
+static int
+MR_get_var_number(Word debugger_request)
+{
+	int result;
+
+	result = MR_DI_get_var_number(debugger_request);
+	return result;
+}
 #endif /* MR_USE_EXTERNAL_DEBUGGER */


Index: mercury_trace_util.c
===================================================================
RCS file:
/home/mercury1/repository/mercury/runtime/mercury_trace_util.c,v
retrieving revision 1.7
diff -u -r1.7 mercury_trace_util.c
--- mercury_trace_util.c	1998/07/22 07:53:25	1.7
+++ mercury_trace_util.c	1998/07/28 06:54:47
@@ -314,6 +314,34 @@
 	return succeeded;
 }
 
+bool
+MR_trace_get_type(const MR_Stack_Layout_Var *var,
+	Word *type_params, Word *type_info)
+{
+	return MR_trace_get_type_base(var, TRUE,
+		MR_saved_sp(MR_saved_regs), MR_saved_curfr(MR_saved_regs),
+		type_params, type_info);
+}
+
+bool
+MR_trace_get_type_base(const MR_Stack_Layout_Var *var,
+	bool saved_regs_valid, Word *base_sp, Word *base_curfr,
+	Word *type_params, Word *type_info)
+{
+	bool	succeeded;
+	Word	*pseudo_type_info;
+	int	i;
+
+	if (!MR_LIVE_TYPE_IS_VAR(var->MR_slv_live_type)) {
+		return FALSE;
+	}
+
+	pseudo_type_info = MR_LIVE_TYPE_GET_VAR_TYPE(var->MR_slv_live_type);
+	*type_info = (Word) MR_create_type_info(type_params,
pseudo_type_info);
+	
+	return TRUE;
+}
+
 void
 MR_trace_write_variable(Word type_info, Word value)
 {

Index: mercury_trace_util.h
===================================================================
RCS file:
/home/mercury1/repository/mercury/runtime/mercury_trace_util.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_trace_util.h
--- mercury_trace_util.h	1998/07/22 07:53:26	1.4
+++ mercury_trace_util.h	1998/07/28 06:54:42
@@ -27,6 +27,12 @@
 extern	bool	MR_trace_get_type_and_value_base(const MR_Stack_Layout_Var
*var,
 			bool saved_regs_valid, Word *base_sp, Word *base_curfr,
 			Word *type_params, Word *type_info, Word *value);
+extern	bool	MR_trace_get_type(const MR_Stack_Layout_Var *var,
+			Word *type_params, Word *type_info);
+extern	bool	MR_trace_get_type_base(const MR_Stack_Layout_Var *var,
+			bool saved_regs_valid, Word *base_sp, Word *base_curfr,
+			Word *type_params, Word *type_info);
+
 
 /*
 ** MR_trace_write_variable:


Index: mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.11
diff -u -r1.11 mercury_wrapper.h
--- mercury_wrapper.h	1998/07/27 15:25:37	1.11
+++ mercury_wrapper.h	1998/07/28 06:52:19
@@ -59,15 +59,32 @@
 */
 void	(*MR_DI_output_current_vars)(Word, Word, Word);
 		/* normally ML_DI_output_current_vars (output_current_vars/3) */
+void	(*MR_DI_output_current_nth_var)(Word, Word);
+		/* normally ML_DI_output_current_nth_var 
+						 (output_current_nth_var/2) */
+void	(*MR_DI_output_current_live_var_names)(Word, Word, Word);
+		/* normally ML_DI_output_current_live_var_names
+					   (output_current_live_var_names/5) */
 void	(*MR_DI_output_current_slots)(Integer, Integer, Integer, Word,
String,
 		String, Integer, Integer, Integer, String, Word);
 		/* normally ML_DI_output_current_slots (output_current_slots/13) */
 bool	(*MR_DI_found_match)(Integer, Integer, Integer, Word, String,
String,
 		Integer, Integer, Integer, Word, String, Word);
 		/* normally ML_DI_found_match (found_match/12) */
+int	(*MR_DI_get_var_number)(Word);
+		/* normally ML_DI_get_var_number (get_var_number/1) */
 void	(*MR_DI_read_request_from_socket)(Word, Word *, Integer *);
 		/* normally ML_DI_read_request_from_socket
 		   (read_request_from_socket/5) */
+
+/*
+** type_name/1 is defined in library/std_util.m and MR_type_name is
used
+** in runtime/mercury_trace_external.c
+*/
+
+String	(*MR_type_name)(Word);
+		/* normally ML_type_name (type_name/1) */ 
+
 
 extern	void		do_init_modules(void);
 

RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
Index: mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.38
diff -u -r1.38 mkinit.c
--- mkinit.c    1998/07/27 19:45:08     1.38
+++ mkinit.c    1998/07/28 08:05:35
@@ -136,8 +136,13 @@
        "       MR_library_finalizer = ML_io_finalize_state;\n"
        "       MR_library_trace_browser =
ENTRY(mercury__io__print_3_0);\n"
        "#ifdef MR_USE_EXTERNAL_DEBUGGER\n"
+       "       MR_type_name = ML_type_name;\n"
        "       MR_DI_output_current_vars =
ML_DI_output_current_vars;\n"
+       "       MR_DI_output_current_nth_var =
ML_DI_output_current_nth_var;\n"
+       "       MR_DI_output_current_live_var_names =
+                       ML_DI_output_current_live_var_names;\n"
        "       MR_DI_output_current_slots =
ML_DI_output_current_slots;\n"
+       "       MR_DI_get_var_number = ML_DI_get_var_number;\n"
        "       MR_DI_found_match = ML_DI_found_match;\n"
        "       MR_DI_read_request_from_socket =
ML_DI_read_request_from_socket;
\n"
        "#endif\n"


-- 
R1.



More information about the developers mailing list