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