For review: Stacks dump in the external debugger (round 2)
Erwan Jahier
Erwan.Jahier at irisa.fr
Tue Feb 16 23:49:15 AEDT 1999
This change implement stack dump commands for the external debugger.
The MR_dump_stack_record_print() defined in runtime/mercury_stack_trace.c is
the function that prints the contents of the stack. We move the definition of
this function to mercury_trace_internal.c and we pass down that function as a
parameter of MR_dump_stack_from_layout(). The rational for this change is that
we can then define a new MR_dump_stack_record_print() in
mercury_trace_external.c that prints the data to the socket as a Prolog term
and pass down the address of that new function to MR_dump_stack_from_layout().
browser/debugger_interface.m:
Add three new kinds of requests: stack, nondet_stack and stack_regs.
trace/mercury_trace_external.c:
Define new MR_dump_stack_record_print() and MR_print_proc_id() that
sends data to the socket as Prolog terms.
Implement the ancestors, non det and registers stack dump.
runtime/mercury_stack_trace.[ch]
trace/mercury_trace.[ch]:
trace/mercury_trace_internal.[ch]:
Moves the definition of MR_dump_stack_record_print(), MR_print_proc_id()
and MR_print_proc_id_for_debugger() from mercury_stack_trace.c to
mercury_trace_internal.c.
Add MR_dump_stack_record_print() as an argument of all the
functions that needs it in mercury_stack_trace.c.
Moves the definition of detism_names() from mercury_stack_trace.c
to mercury_trace.c. This function is needed by both version of
MR_dump_stack_record_print().
Index: browser/debugger_interface.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/debugger_interface.m,v
retrieving revision 1.5
diff -u -r1.5 debugger_interface.m
--- debugger_interface.m 1999/02/10 22:31:27 1.5
+++ debugger_interface.m 1999/02/16 12:40:17
@@ -118,6 +118,14 @@
% restarts execution at the call port of the call
% corresponding to the current event
; retry
+ % print the ancestors stack
+ ; stack
+ % prints the contents of the fixed slots of the
+ % frames on the nondet stack
+ ; nondet_stack
+ % print the contents of the virtual machine registers
+ % that point to the det and nondet stacks
+ ; stack_regs
% something went wrong when trying to get the
% next request
; error(string)
@@ -383,6 +391,9 @@
classify_request(current_live_var_names, 7).
classify_request(current_nth_var(_), 8).
classify_request(retry, 9).
+classify_request(stack, 10).
+classify_request(nondet_stack, 11).
+classify_request(stack_regs, 12).
%-----------------------------------------------------------------------------%
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.24
diff -u -r1.24 mercury_stack_trace.c
--- mercury_stack_trace.c 1998/12/17 13:36:59 1.24
+++ mercury_stack_trace.c 1999/02/16 12:40:34
@@ -15,32 +15,17 @@
#include <stdio.h>
-static const char * detism_names[] = {
- "failure", /* 0 */
- "", /* 1 */
- "semidet", /* 2 */
- "nondet", /* 3 */
- "erroneous", /* 4 */
- "", /* 5 */
- "det", /* 6 */
- "multi", /* 7 */
- "", /* 8 */
- "", /* 9 */
- "cc_nondet", /* 10 */
- "", /* 11 */
- "", /* 12 */
- "", /* 13 */
- "cc_multi" /* 14 */
-};
-
static void MR_dump_stack_record_init(void);
static void MR_dump_stack_record_frame(FILE *fp,
const MR_Stack_Layout_Entry *,
- Word *base_sp, Word *base_curfr);
-static void MR_dump_stack_record_flush(FILE *fp);
-static void MR_dump_stack_record_print(FILE *fp,
- const MR_Stack_Layout_Entry *, int, int,
- Word *base_sp, Word *base_curfr);
+ Word *base_sp, Word *base_curfr,
+ void *MR_dump_stack_record_print(
+ FILE *, const MR_Stack_Layout_Entry *,
+ int, int, Word *, Word *));
+static void MR_dump_stack_record_flush(FILE *fp,
+ void *MR_dump_stack_record_print(
+ FILE *, const MR_Stack_Layout_Entry *,
+ int, int, Word *, Word *));
void
MR_dump_stack(Code *success_pointer, Word *det_stack_pointer,
@@ -75,7 +60,9 @@
const char *
MR_dump_stack_from_layout(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
- Word *det_stack_pointer, Word *current_frame, bool include_trace_data)
+ Word *det_stack_pointer, Word *current_frame, bool include_trace_data,
+ void *MR_dump_stack_record_print(FILE *, const MR_Stack_Layout_Entry *,
+ int, int, Word *, Word *))
{
MR_Stack_Walk_Step_Result result;
const MR_Stack_Layout_Label *return_label_layout;
@@ -98,26 +85,30 @@
result = MR_stack_walk_step(entry_layout, &return_label_layout,
&stack_trace_sp, &stack_trace_curfr, &problem);
if (result == STEP_ERROR_BEFORE) {
- MR_dump_stack_record_flush(fp);
+ MR_dump_stack_record_flush(fp,
+ MR_dump_stack_record_print);
return problem;
} else if (result == STEP_ERROR_AFTER) {
if (include_trace_data) {
MR_dump_stack_record_frame(fp, entry_layout,
- old_trace_sp, old_trace_curfr);
+ old_trace_sp, old_trace_curfr,
+ MR_dump_stack_record_print);
} else {
MR_dump_stack_record_frame(fp, entry_layout,
- NULL, NULL);
+ NULL, NULL, MR_dump_stack_record_print);
}
- MR_dump_stack_record_flush(fp);
+ MR_dump_stack_record_flush(fp,
+ MR_dump_stack_record_print);
return problem;
} else {
if (include_trace_data) {
MR_dump_stack_record_frame(fp, entry_layout,
- old_trace_sp, old_trace_curfr);
+ old_trace_sp, old_trace_curfr,
+ MR_dump_stack_record_print);
} else {
MR_dump_stack_record_frame(fp, entry_layout,
- NULL, NULL);
+ NULL, NULL, MR_dump_stack_record_print);
}
}
@@ -128,7 +119,7 @@
entry_layout = return_label_layout->MR_sll_entry;
} while (TRUE);
- MR_dump_stack_record_flush(fp);
+ MR_dump_stack_record_flush(fp, MR_dump_stack_record_print);
return NULL;
}
@@ -293,7 +284,8 @@
static void
MR_dump_stack_record_frame(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
- Word *base_sp, Word *base_curfr)
+ Word *base_sp, Word *base_curfr, void *MR_dump_stack_record_print(
+ FILE *, const MR_Stack_Layout_Entry *, int, int, Word *, Word *))
{
bool must_flush;
@@ -319,7 +311,7 @@
((base_sp != NULL) || (base_curfr != NULL));
if (must_flush) {
- MR_dump_stack_record_flush(fp);
+ MR_dump_stack_record_flush(fp, MR_dump_stack_record_print);
prev_entry_layout = entry_layout;
prev_entry_layout_count = 1;
@@ -334,7 +326,8 @@
}
static void
-MR_dump_stack_record_flush(FILE *fp)
+MR_dump_stack_record_flush(FILE *fp, void *MR_dump_stack_record_print(
+ FILE *, const MR_Stack_Layout_Entry *, int, int, Word *, Word *))
{
if (prev_entry_layout != NULL) {
MR_dump_stack_record_print(fp, prev_entry_layout,
@@ -343,136 +336,3 @@
}
}
-static void
-MR_dump_stack_record_print(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
- int count, int start_level, Word *base_sp, Word *base_curfr)
-{
- fprintf(fp, "%4d ", start_level);
-
- if (count > 1) {
- fprintf(fp, " %3d* ", count);
- } else if ((base_sp == NULL) && (base_curfr == NULL)) {
- fprintf(fp, "%5s ", "");
- } else {
- /*
- ** If we are printing trace data, we need all the horizonal
- ** room we can get, and there will not be any repeated lines,
- ** so we don't reserve space for the repeat counts.
- */
- }
-
- MR_print_proc_id(fp, entry_layout, NULL, base_sp, base_curfr);
-}
-
-void
-MR_print_proc_id_for_debugger(FILE *fp,
- const MR_Stack_Layout_Entry *entry_layout)
-{
- MR_print_proc_id(fp, entry_layout, NULL, NULL, NULL);
-}
-
-void
-MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
- const char *extra, Word *base_sp, Word *base_curfr)
-{
- if (! MR_ENTRY_LAYOUT_HAS_PROC_ID(entry)) {
- fatal_error("cannot print procedure id without layout");
- }
-
- if (base_sp != NULL && base_curfr != NULL) {
- bool print_details = FALSE;
- if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
- Word maybe_from_full = entry->MR_sle_maybe_from_full;
- if (maybe_from_full > 0) {
- /*
- ** for procedures compiled with shallow
- ** tracing, the details will be valid only
- ** if the value of MR_from_full saved in
- ** the appropriate stack slot was TRUE.
- */
- if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
- print_details = MR_based_stackvar(
- base_sp, maybe_from_full);
- } else {
- print_details = MR_based_framevar(
- base_curfr, maybe_from_full);
- }
- } else {
- /*
- ** for procedures compiled with full tracing,
- ** always print out the details
- */
- print_details = TRUE;
- }
- }
- if (print_details) {
- if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
- fprintf(fp, "%7lu %7lu %4lu ",
- (unsigned long)
- MR_event_num_stackvar(base_sp) + 1,
- (unsigned long)
- MR_call_num_stackvar(base_sp),
- (unsigned long)
- MR_call_depth_stackvar(base_sp));
- } else {
- fprintf(fp, "%7lu %7lu %4lu ",
- (unsigned long)
- MR_event_num_framevar(base_curfr) + 1,
- (unsigned long)
- MR_call_num_framevar(base_curfr),
- (unsigned long)
- MR_call_depth_framevar(base_curfr));
- }
- } else {
- /* ensure that the remaining columns line up */
- fprintf(fp, "%21s", "");
- }
- }
-
- if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
- fprintf(fp, "%s for %s:%s/%ld-%ld",
- entry->MR_sle_comp.MR_comp_pred_name,
- entry->MR_sle_comp.MR_comp_type_module,
- entry->MR_sle_comp.MR_comp_type_name,
- (long) entry->MR_sle_comp.MR_comp_arity,
- (long) entry->MR_sle_comp.MR_comp_mode);
-
- if (strcmp(entry->MR_sle_comp.MR_comp_type_module,
- entry->MR_sle_comp.MR_comp_def_module) != 0)
- {
- fprintf(fp, " {%s}",
- entry->MR_sle_comp.MR_comp_def_module);
- }
- } else {
- if (entry->MR_sle_user.MR_user_pred_or_func == MR_PREDICATE) {
- fprintf(fp, "pred");
- } else if (entry->MR_sle_user.MR_user_pred_or_func ==
- MR_FUNCTION)
- {
- fprintf(fp, "func");
- } else {
- fatal_error("procedure is not pred or func");
- }
-
- fprintf(fp, " %s:%s/%ld-%ld",
- entry->MR_sle_user.MR_user_decl_module,
- entry->MR_sle_user.MR_user_name,
- (long) entry->MR_sle_user.MR_user_arity,
- (long) entry->MR_sle_user.MR_user_mode);
-
- if (strcmp(entry->MR_sle_user.MR_user_decl_module,
- entry->MR_sle_user.MR_user_def_module) != 0)
- {
- fprintf(fp, " {%s}",
- entry->MR_sle_user.MR_user_def_module);
- }
- }
-
- fprintf(fp, " (%s)", detism_names[entry->MR_sle_detism]);
-
- if (extra != NULL) {
- fprintf(fp, " %s\n", extra);
- } else {
- fprintf(fp, "\n");
- }
-}
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.14
diff -u -r1.14 mercury_stack_trace.h
--- mercury_stack_trace.h 1998/12/17 13:37:00 1.14
+++ mercury_stack_trace.h 1999/02/16 12:40:35
@@ -56,7 +56,10 @@
extern const char *MR_dump_stack_from_layout(FILE *fp,
const MR_Stack_Layout_Entry *entry_layout,
Word *det_stack_pointer, Word *current_frame,
- bool include_trace_data);
+ bool include_trace_data,
+ void *MR_dump_stack_record_print(FILE *,
+ const MR_Stack_Layout_Entry *,
+ int, int, Word *, Word *));
/*
** MR_dump_nondet_stack_from_layout:
@@ -134,20 +137,5 @@
Word *MR_nondet_stack_trace_bottom;
-/*
-** MR_print_proc_id prints an identification of the given procedure,
-** consisting of "pred" or "func", module name, pred or func name, arity,
-** mode number and determinism, followed by an optional extra string,
-** and a newline.
-**
-** If the procedure has trace layout information and the relevant one of
-** base_sp and base_curfr is not NULL, it also prints the call event number,
-** call sequence number and call depth of the call.
-*/
-
-extern void MR_print_proc_id_for_debugger(FILE *fp,
- const MR_Stack_Layout_Entry *entry);
-extern void MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
- const char *extra, Word *base_sp, Word *base_curfr);
#endif /* MERCURY_STACK_TRACE_H */
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.5
diff -u -r1.5 mercury_trace.c
--- mercury_trace.c 1999/02/12 00:16:42 1.5
+++ mercury_trace.c 1999/02/16 12:40:36
@@ -432,3 +432,21 @@
*succeeded = FALSE;
return 0;
}
+
+extern const char * detism_names[] = {
+ "failure", /* 0 */
+ "", /* 1 */
+ "semidet", /* 2 */
+ "nondet", /* 3 */
+ "erroneous", /* 4 */
+ "", /* 5 */
+ "det", /* 6 */
+ "multi", /* 7 */
+ "", /* 8 */
+ "", /* 9 */
+ "cc_nondet", /* 10 */
+ "", /* 11 */
+ "", /* 12 */
+ "", /* 13 */
+ "cc_multi" /* 14 */
+};
Index: trace/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_trace.h
--- mercury_trace.h 1999/02/12 00:16:43 1.5
+++ mercury_trace.h 1999/02/16 12:40:36
@@ -98,6 +98,8 @@
bool MR_trace_must_check;
} MR_Trace_Cmd_Info;
+extern const char * detism_names[];
+
#define MR_port_is_final(port) ((port) == MR_PORT_EXIT || \
(port) == MR_PORT_FAIL || \
(port) == MR_PORT_EXCEPTION)
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.6
diff -u -r1.6 mercury_trace_external.c
--- mercury_trace_external.c 1999/02/10 22:31:23 1.6
+++ mercury_trace_external.c 1999/02/16 12:40:38
@@ -53,12 +53,16 @@
MR_REQUEST_ERROR = 6, /* something went wrong */
MR_REQUEST_CURRENT_LIVE_VAR_NAMES
= 7, /* report data for
- current_live_var_names query */
+ current_live_var_names query */
MR_REQUEST_CURRENT_NTH_VAR
= 8, /* report data for
- current_nth_var query */
- MR_REQUEST_RETRY = 9 /* restart the execution to the call
+ current_nth_var query */
+ MR_REQUEST_RETRY = 9, /* restart the execution to the call
port of the current event */
+ MR_REQUEST_STACK = 10,/* print the ancestors list */
+ MR_REQUEST_NONDET_STACK = 11,/* print the non det stack */
+ MR_REQUEST_STACK_REGS = 12 /* prints the contents of the virtual
+ machine registers. */
} MR_debugger_request_type;
@@ -90,6 +94,11 @@
static Word MR_trace_make_nth_var(const MR_Stack_Layout_Label *layout,
Word *saved_regs, Word debugger_request);
static int MR_get_var_number(Word debugger_request);
+static void MR_print_proc_id_to_socket(const MR_Stack_Layout_Entry *entry,
+ const char *extra, Word *base_sp, Word *base_curfr);
+static void MR_dump_stack_record_print_to_socket(FILE *fp,
+ const MR_Stack_Layout_Entry *entry_layout, int count,
+ int start_level, Word *base_sp, Word *base_curfr);
#if 0
This pseudocode should go in the debugger process:
@@ -344,6 +353,7 @@
Code *jumpaddr = NULL;
MR_Event_Details event_details;
char *message;
+ bool include_trace_data = TRUE;
event_details.MR_call_seqno = MR_trace_call_seqno;
event_details.MR_call_depth = MR_trace_call_depth;
@@ -444,7 +454,65 @@
"error(\"%s\").\n", message);
}
break;
-
+
+ case MR_REQUEST_STACK:
+ if (MR_debug_socket) {
+ fprintf(stderr, "\nMercury runtime: "
+ "REQUEST_STACK\n");
+ }
+ do_init_modules();
+ message = MR_dump_stack_from_layout(
+ stdout,
+ layout->MR_sll_entry,
+ MR_saved_sp(saved_regs),
+ MR_saved_curfr(saved_regs),
+ include_trace_data,
+ &MR_dump_stack_record_print_to_socket);
+ MR_send_message_to_socket("end_stack");
+ if (message != NULL) {
+ MR_send_message_to_socket_format(
+ "error(\"%s\").\n", message);
+ } else {
+ MR_send_message_to_socket("ok");
+ }
+ break;
+
+ case MR_REQUEST_NONDET_STACK:
+ if (MR_debug_socket) {
+ fprintf(stderr, "\nMercury runtime: "
+ "REQUEST_NONDET_STACK\n");
+ }
+ do_init_modules();
+ /*
+ ** XXX As in stack dump, we could send the
+ ** output of this function on the socket. But the
+ ** outputs are done via fprintf() and printlabel(),
+ ** so we would need to define new fprintf)() and
+ ** printlabel() and pass them down as parameters of
+ ** MR_dump_nondet_stack_from_layout() (as we do
+ ** with MR_dump_stack_record_print()).
+ */
+ MR_dump_nondet_stack_from_layout(stdout,
+ MR_saved_maxfr(saved_regs));
+ MR_send_message_to_socket("ok");
+ break;
+
+ case MR_REQUEST_STACK_REGS:
+ if (MR_debug_socket) {
+ fprintf(stderr, "\nMercury runtime: "
+ "REQUEST_STACK_REGS\n");
+ }
+ MR_send_message_to_socket_format(
+ "sp(\"%p\").\n",
+ (char *) MR_saved_sp(saved_regs));
+ MR_send_message_to_socket_format(
+ "curfr(\"%p\").\n",
+ (char *) MR_saved_curfr(saved_regs));
+ MR_send_message_to_socket_format(
+ "maxfr(\"%p\").\n",
+ (char *) MR_saved_maxfr(saved_regs));
+ break;
+
case MR_REQUEST_NO_TRACE:
cmd->MR_trace_cmd = MR_CMD_TO_END;
return jumpaddr;
@@ -738,3 +806,142 @@
return num;
}
#endif /* MR_USE_EXTERNAL_DEBUGGER */
+
+
+static void
+MR_dump_stack_record_print_to_socket(FILE *fp,
+ const MR_Stack_Layout_Entry *entry_layout, int count, int start_level,
+ Word *base_sp, Word *base_curfr)
+{
+ MR_send_message_to_socket_format( "%d.\n ", (char *) start_level);
+
+ if (count > 1) {
+ MR_send_message_to_socket_format( " %d*.\n ", (char *) count);
+ } else if ((base_sp == NULL) && (base_curfr == NULL)) {
+ MR_send_message_to_socket_format( "%s.\n ", "r1");
+ }
+
+ MR_print_proc_id_to_socket(entry_layout, NULL, base_sp, base_curfr);
+}
+
+
+static void
+MR_print_proc_id_to_socket(const MR_Stack_Layout_Entry *entry,
+ const char *extra, Word *base_sp, Word *base_curfr)
+{
+ if (! MR_ENTRY_LAYOUT_HAS_PROC_ID(entry)) {
+ fatal_error("cannot retrieve procedure id without layout");
+ }
+
+ if (base_sp != NULL && base_curfr != NULL) {
+ bool print_details = FALSE;
+ if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
+ Word maybe_from_full = entry->MR_sle_maybe_from_full;
+ if (maybe_from_full > 0) {
+ /*
+ ** for procedures compiled with shallow
+ ** tracing, the details will be valid only
+ ** if the value of MR_from_full saved in
+ ** the appropriate stack slot was TRUE.
+ */
+ if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
+ print_details = MR_based_stackvar(
+ base_sp, maybe_from_full);
+ } else {
+ print_details = MR_based_framevar(
+ base_curfr, maybe_from_full);
+ }
+ } else {
+ /*
+ ** for procedures compiled with full tracing,
+ ** always print out the details
+ */
+ print_details = TRUE;
+ }
+ }
+ if (print_details) {
+ if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
+ MR_send_message_to_socket_format(
+ "%7lu.\n",
+ (char *)
+ MR_event_num_stackvar(base_sp) + 1);
+ MR_send_message_to_socket_format(
+ " %7lu.\n",
+ (char *)
+ MR_call_num_stackvar(base_sp));
+ MR_send_message_to_socket_format(
+ "%4lu.\n",
+ (char *)
+ MR_call_depth_stackvar(base_sp));
+ } else {
+ MR_send_message_to_socket_format(
+ "%7lu.\n",
+ (char *)
+ MR_event_num_framevar(base_curfr) + 1);
+ MR_send_message_to_socket_format(
+ "%7lu.\n",
+ (char *)
+ MR_call_num_framevar(base_curfr));
+ MR_send_message_to_socket_format(
+ "%4lu.\n",
+ (char *)
+ MR_call_depth_framevar(base_curfr));
+ }
+ }
+ }
+
+ if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
+ MR_send_message_to_socket_format( "%s.\n",
+ entry->MR_sle_comp.MR_comp_pred_name);
+ MR_send_message_to_socket("for");
+ MR_send_message_to_socket_format( "%s.\n",
+ entry->MR_sle_comp.MR_comp_type_module);
+ MR_send_message_to_socket_format( "%s.\n",
+ entry->MR_sle_comp.MR_comp_type_name);
+ MR_send_message_to_socket_format( "%ld.\n",
+ (char *) entry->MR_sle_comp.MR_comp_arity);
+ MR_send_message_to_socket_format( "%ld.\n",
+ (char *) entry->MR_sle_comp.MR_comp_mode);
+
+ if (strcmp(entry->MR_sle_comp.MR_comp_type_module,
+ entry->MR_sle_comp.MR_comp_def_module) != 0)
+ {
+ MR_send_message_to_socket_format( " {%s}.\n",
+ entry->MR_sle_comp.MR_comp_def_module);
+ }
+ } else {
+ if (entry->MR_sle_user.MR_user_pred_or_func == MR_PREDICATE) {
+ MR_send_message_to_socket("pred");
+ } else if (entry->MR_sle_user.MR_user_pred_or_func ==
+ MR_FUNCTION)
+ {
+ MR_send_message_to_socket( "func.\n");
+ } else {
+ fatal_error("procedure is not pred or func");
+ }
+
+ MR_send_message_to_socket_format( "%s.\n",
+ entry->MR_sle_user.MR_user_decl_module);
+ MR_send_message_to_socket_format( "%s.\n",
+ entry->MR_sle_user.MR_user_name);
+ MR_send_message_to_socket_format( "%ld.\n",
+ (char *) entry->MR_sle_user.MR_user_arity);
+ MR_send_message_to_socket_format( "%ld.\n",
+ (char *) entry->MR_sle_user.MR_user_mode);
+
+ if (strcmp(entry->MR_sle_user.MR_user_decl_module,
+ entry->MR_sle_user.MR_user_def_module) != 0)
+ {
+ MR_send_message_to_socket_format( "{%s}.\n",
+ entry->MR_sle_user.MR_user_def_module);
+ }
+ }
+
+ MR_send_message_to_socket_format( "%s.\n",
+ detism_names[entry->MR_sle_detism]);
+
+ if (extra != NULL) {
+ MR_send_message_to_socket_format( " %s.\n", extra);
+ }
+ MR_send_message_to_socket("end_proc");
+}
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.26
diff -u -r1.26 mercury_trace_internal.c
--- mercury_trace_internal.c 1999/02/12 02:50:01 1.26
+++ mercury_trace_internal.c 1999/02/16 12:40:42
@@ -215,6 +215,10 @@
static bool MR_trace_valid_command(const char *word);
+static void MR_dump_stack_record_print(FILE *fp,
+ const MR_Stack_Layout_Entry *, int, int,
+ Word *base_sp, Word *base_curfr);
+
Code *
MR_trace_event_internal(MR_Trace_Cmd_Info *cmd, bool interactive,
const MR_Stack_Layout_Label *layout, Word *saved_regs,
@@ -789,7 +793,8 @@
layout->MR_sll_entry,
MR_saved_sp(saved_regs),
MR_saved_curfr(saved_regs),
- include_trace_data);
+ include_trace_data,
+ &MR_dump_stack_record_print);
if (msg != NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "%s.\n", msg);
@@ -2459,4 +2464,138 @@
}
return FALSE;
+}
+
+static void
+MR_dump_stack_record_print(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
+ int count, int start_level, Word *base_sp, Word *base_curfr)
+{
+ fprintf(fp, "%4d ", start_level);
+
+ if (count > 1) {
+ fprintf(fp, " %3d* ", count);
+ } else if ((base_sp == NULL) && (base_curfr == NULL)) {
+ fprintf(fp, "%5s ", "");
+ } else {
+ /*
+ ** If we are printing trace data, we need all the horizonal
+ ** room we can get, and there will not be any repeated lines,
+ ** so we don't reserve space for the repeat counts.
+ */
+ }
+
+ MR_print_proc_id(fp, entry_layout, NULL, base_sp, base_curfr);
+}
+
+void
+MR_print_proc_id_for_debugger(FILE *fp,
+ const MR_Stack_Layout_Entry *entry_layout)
+{
+ MR_print_proc_id(fp, entry_layout, NULL, NULL, NULL);
+}
+
+void
+MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
+ const char *extra, Word *base_sp, Word *base_curfr)
+{
+ if (! MR_ENTRY_LAYOUT_HAS_PROC_ID(entry)) {
+ fatal_error("cannot print procedure id without layout");
+ }
+
+ if (base_sp != NULL && base_curfr != NULL) {
+ bool print_details = FALSE;
+ if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
+ Word maybe_from_full = entry->MR_sle_maybe_from_full;
+ if (maybe_from_full > 0) {
+ /*
+ ** for procedures compiled with shallow
+ ** tracing, the details will be valid only
+ ** if the value of MR_from_full saved in
+ ** the appropriate stack slot was TRUE.
+ */
+ if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
+ print_details = MR_based_stackvar(
+ base_sp, maybe_from_full);
+ } else {
+ print_details = MR_based_framevar(
+ base_curfr, maybe_from_full);
+ }
+ } else {
+ /*
+ ** for procedures compiled with full tracing,
+ ** always print out the details
+ */
+ print_details = TRUE;
+ }
+ }
+ if (print_details) {
+ if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
+ fprintf(fp, "%7lu %7lu %4lu ",
+ (unsigned long)
+ MR_event_num_stackvar(base_sp) + 1,
+ (unsigned long)
+ MR_call_num_stackvar(base_sp),
+ (unsigned long)
+ MR_call_depth_stackvar(base_sp));
+ } else {
+ fprintf(fp, "%7lu %7lu %4lu ",
+ (unsigned long)
+ MR_event_num_framevar(base_curfr) + 1,
+ (unsigned long)
+ MR_call_num_framevar(base_curfr),
+ (unsigned long)
+ MR_call_depth_framevar(base_curfr));
+ }
+ } else {
+ /* ensure that the remaining columns line up */
+ fprintf(fp, "%21s", "");
+ }
+ }
+
+ if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
+ fprintf(fp, "%s for %s:%s/%ld-%ld",
+ entry->MR_sle_comp.MR_comp_pred_name,
+ entry->MR_sle_comp.MR_comp_type_module,
+ entry->MR_sle_comp.MR_comp_type_name,
+ (long) entry->MR_sle_comp.MR_comp_arity,
+ (long) entry->MR_sle_comp.MR_comp_mode);
+
+ if (strcmp(entry->MR_sle_comp.MR_comp_type_module,
+ entry->MR_sle_comp.MR_comp_def_module) != 0)
+ {
+ fprintf(fp, " {%s}",
+ entry->MR_sle_comp.MR_comp_def_module);
+ }
+ } else {
+ if (entry->MR_sle_user.MR_user_pred_or_func == MR_PREDICATE) {
+ fprintf(fp, "pred");
+ } else if (entry->MR_sle_user.MR_user_pred_or_func ==
+ MR_FUNCTION)
+ {
+ fprintf(fp, "func");
+ } else {
+ fatal_error("procedure is not pred or func");
+ }
+
+ fprintf(fp, " %s:%s/%ld-%ld",
+ entry->MR_sle_user.MR_user_decl_module,
+ entry->MR_sle_user.MR_user_name,
+ (long) entry->MR_sle_user.MR_user_arity,
+ (long) entry->MR_sle_user.MR_user_mode);
+
+ if (strcmp(entry->MR_sle_user.MR_user_decl_module,
+ entry->MR_sle_user.MR_user_def_module) != 0)
+ {
+ fprintf(fp, " {%s}",
+ entry->MR_sle_user.MR_user_def_module);
+ }
+ }
+
+ fprintf(fp, " (%s)", detism_names[entry->MR_sle_detism]);
+
+ if (extra != NULL) {
+ fprintf(fp, " %s\n", extra);
+ } else {
+ fprintf(fp, "\n");
+ }
}
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_trace_internal.h
--- mercury_trace_internal.h 1999/02/10 22:31:22 1.5
+++ mercury_trace_internal.h 1999/02/16 12:40:42
@@ -49,6 +49,22 @@
const char *path, int *max_mr_num);
/*
+** MR_print_proc_id prints an identification of the given procedure,
+** consisting of "pred" or "func", module name, pred or func name, arity,
+** mode number and determinism, followed by an optional extra string,
+** and a newline.
+**
+** If the procedure has trace layout information and the relevant one of
+** base_sp and base_curfr is not NULL, it also prints the call event number,
+** call sequence number and call depth of the call.
+*/
+
+extern void MR_print_proc_id_for_debugger(FILE *fp,
+ const MR_Stack_Layout_Entry *entry);
+extern void MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
+ const char *extra, Word *base_sp, Word *base_curfr);
+
+/*
** Debugger I/O streams.
** Replacements for stdin/stdout/stderr respectively.
**
--
R1.
More information about the developers
mailing list