[m-dev.] For review: Stacks dump in the external debugger (round 2)
Erwan Jahier
Erwan.Jahier at irisa.fr
Wed Feb 17 07:28:26 AEDT 1999
| On 16-Feb-1999, Erwan Jahier <Erwan.Jahier at irisa.fr> wrote:
| >
| > --- mercury_trace.c 1999/02/12 00:16:42 1.5
| > +++ mercury_trace.c 1999/02/16 16:26:48
| > @@ -432,3 +432,28 @@
| > *succeeded = FALSE;
| > return 0;
| > }
| > +
| > +
| > +/*
| > +** The different Mercury determinisms are internaly represented by integers.
|
| s/internaly/internally
Ok.
|
| > +** This array gives the correspondance with the internal representation and
| > +** the names that are usually used to denote determinisms.
| > +*/
| > +
| > +extern const char * MR_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 16:26:48
| > @@ -98,6 +98,8 @@
| > bool MR_trace_must_check;
| > } MR_Trace_Cmd_Info;
| >
| > +extern const char * MR_detism_names[];
|
| The comment above should go on the declaration here in the header file,
| instead of, or as well as, on the definition in mercury_trace.c.
I will recopy it in mercury_trace.c.
|
| > + case MR_REQUEST_STACK_REGS:
| > + if (MR_debug_socket) {
| > + fprintf(stderr, "\nMercury runtime: "
| > + "REQUEST_STACK_REGS\n");
| > + }
| > + MR_send_message_to_socket_format(
| > + "stack_regs(\"sp = %p, curfr = %p, "
| > + "maxfr = %p\").\n",
| > + MR_saved_sp(saved_regs),
| > + MR_saved_curfr(saved_regs),
| > + MR_saved_maxfr(saved_regs));
| > + break;
|
| The "%p" format is not guaranteed to give you a syntactically correct
| Prolog term. On some systems, "%p" will give you a hexadecimal number,
| without any "0x" prefix, e.g. "0000ffff", which is not a syntactically
| correct Prolog term.
|
| I suggest you use "%lu", and cast to `unsigned long'.
Well I was sending a string here (note the \") which is a valid Prolog term.
But I'll do as you suggest anyway.
| However, even better would be to put something like
|
| typedef unsigned long MR_intmax_t;
| #define MR_PRINTF_INTMAX_T "%lu"
|
| in somewhere like runtime/mercury_types.h and then use those.
|
| > -static void
| > -MR_send_message_to_socket_format(const char *format, const char *message)
| > +void
| > +MR_send_message_to_socket_format(const char *format, ...)
|
| Any particular reason why this became non-static?
No. Indeed I was confused by your comments.
| Sorry if my comments about "in header file", "in C file" confused you,
| but if this function isn't used from any other module, then there
| is no need to make it extern and declare it in the header file,
| instead it should remain static and the declaration should be moved
| from the header file to the start of the C file.
|
| > +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 ", start_level);
|
| Why the space after the \n ?
No reason. I'll remove it.
| > + if (count > 1) {
| > + MR_send_message_to_socket_format( " %d*.\n ", count);
|
| "1*." is not valid syntax for a Prolog term.
|
| > + } else if ((base_sp == NULL) && (base_curfr == NULL)) {
| > + MR_send_message_to_socket_format( "%s.\n ", "r1");
| > + }
|
| Why does it send "r1." in this case? A comment might help.
| Also why use ("%s.\n", "r1") instead of just ("r1.\n")?
Oops. This old debugging code. I will remove it.
| > + if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
| > + MR_send_message_to_socket_format(
| > + "proc(%s for %s:%s/%ld-%ld).\n",
|
| That won't be valid syntax for a Prolog term.
| I suggest
|
| "proc('%s for %s:%s'/%ld-%ld).\n"
|
| which should work OK except when one of the names contains a
| single quote ("'").
Can it happen?
Isn't that a problem?
|
| > + 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);
| > + }
|
| Likewise appending {...} won't be valid syntax for a Prolog term.
|
| > + } 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");
|
| Why do you print ".\n" for funcs but not for preds?
| That is probably a mistake.
Indeed.
| > + MR_send_message_to_socket_format(
| > + "proc(%s:%s/%ld-%ld).\n",
|
| I suggest
|
| "proc('%s:%s'/%ld-%ld).\n",
| ^ ^
Ok.
| > + 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);
| > + }
|
| As above, that needs fixing.
|
| > + MR_send_message_to_socket_format( "%s.\n",
| > + MR_detism_names[entry->MR_sle_detism]);
| > +
| > + if (extra != NULL) {
| > + MR_send_message_to_socket_format( " %s.\n", extra);
| > + }
|
| Shouldn't that be sent as a string or an atom or something?
| i.e. in quotes?
Yes.
But in fact, extra is always NULL except if it is called from
MR_trace_event_print_internal_report() which is can only be called from the
internal debugger. So I will remove that message.
|
| > + MR_send_message_to_socket("end_proc");
| > +}
This one was not necessary. I'll remove it.
|
| It would be a good idea to document the protocol that is
| used by mercury_trace_external.c to communicate with the external
| debugger, especially since that protocol is becoming quite
| complex now.
Yes, it is a good idea. I'll do that.
|
| > 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 16:26:52
| > @@ -48,6 +48,7 @@
| > MR_Trace_Port port, int seqno, int depth,
| > const char *path, int *max_mr_num);
| >
| > +
| > /*
| > ** Debugger I/O streams.
| > ** Replacements for stdin/stdout/stderr respectively.
|
| Please undo that accidental change.
Ok.
|
| I'd like to see another diff please.
*************************************************************************
* relative diff *
*************************************************************************
Index: trace/mercury_trace_external.c
--- 0.11/trace/mercury_trace_external.c Tue, 16 Feb 1999 17:49:57 +0100 jahier (submitdiff/5_mercury_tr 1.10 640)
+++ 0.11(w)/trace/mercury_trace_external.c Tue, 16 Feb 1999 21:14:45 +0100 jahier (submitdiff/5_mercury_tr 1.10 640)
@@ -70,6 +70,21 @@
static MercuryFile MR_debugger_socket_in;
static MercuryFile MR_debugger_socket_out;
+/*
+** Use a GNU C extension to enforce static type checking
+** for printf-style functions.
+** (See the "Function attributes" section of "C extensions"
+** chapter of the GNU C manual for detailed documentation.)
+*/
+#ifdef __GNUC__
+ #define MR_LIKE_PRINTF(format_argnum, vars_argnum) \
+ __attribute__ ((format (printf, (format_argnum), (vars_argnum))))
+#else
+ #define MR_LIKE_PRINTF(n, m) /* nothing */
+#endif
+void MR_send_message_to_socket_format(const char *format, ...)
+ MR_LIKE_PRINTF(1, 2);
+
static void MR_send_message_to_socket(const char *message);
static void MR_read_request_from_socket(
Word *debugger_request_ptr,
@@ -503,10 +518,12 @@
"REQUEST_STACK_REGS\n");
}
MR_send_message_to_socket_format(
- "stack_regs(\"sp = %p, curfr = %p, "
- "maxfr = %p\").\n",
+ "stack_regs(%lu, %lu, %lu).\n",
+ (unsigned long)
MR_saved_sp(saved_regs),
+ (unsigned long)
MR_saved_curfr(saved_regs),
+ (unsigned long)
MR_saved_maxfr(saved_regs));
break;
@@ -646,7 +663,7 @@
return result;
}
-void
+static void
MR_send_message_to_socket_format(const char *format, ...)
{
va_list args;
@@ -807,22 +824,37 @@
);
return num;
}
-#endif /* MR_USE_EXTERNAL_DEBUGGER */
+/*
+** The protocol between the debugged Mercury program and the external debugger
+** is the following:
+** 1) The debugger sends "stack";
+** 2) For each procedure in the stack that is not generated by the compiler, the
+** debuggee sends:
+** - level(int) (the level of the procedure in the stack)
+** - detail(unsigned long, unsigned long, unsigned long) (the call event
+** number, call sequence number and depth of the goal of the procedure)
+** - the atom 'pred' or 'func' depending if the procedure is a function
+** or not
+** - proc('string:string'/long-long) (the name of the procedure)
+** - det(string) (the determinism of the procedure)
+** - def_module(string) (the name of the defining module if different from
+** the current one)
+**
+** For each compiler generated procedures, the debuggee sends:
+** - level(int) (as above)
+** - detail(unsigned long, unsigned long, unsigned long) (as above)
+** - proc('string for string:string'/long-long) (the name of the
+** compiler-generated procedure)
+** - def_module(string) (as above)
+*/
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 ", start_level);
-
- if (count > 1) {
- MR_send_message_to_socket_format( " %d*.\n ", count);
- } else if ((base_sp == NULL) && (base_curfr == NULL)) {
- MR_send_message_to_socket_format( "%s.\n ", "r1");
- }
-
+ MR_send_message_to_socket_format("level(%d).\n", start_level);
MR_print_proc_id_to_socket(entry_layout, NULL, base_sp, base_curfr);
}
@@ -886,7 +918,7 @@
if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
MR_send_message_to_socket_format(
- "proc(%s for %s:%s/%ld-%ld).\n",
+ "proc('%s for %s:%s'/%ld-%ld).\n",
entry->MR_sle_comp.MR_comp_pred_name,
entry->MR_sle_comp.MR_comp_type_module,
entry->MR_sle_comp.MR_comp_type_name,
@@ -896,7 +928,8 @@
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",
+ MR_send_message_to_socket_format(
+ "def_module(\"%s\").\n",
entry->MR_sle_comp.MR_comp_def_module);
}
} else {
@@ -905,13 +938,13 @@
} else if (entry->MR_sle_user.MR_user_pred_or_func ==
MR_FUNCTION)
{
- MR_send_message_to_socket( "func.\n");
+ MR_send_message_to_socket("func");
} else {
fatal_error("procedure is not pred or func");
}
MR_send_message_to_socket_format(
- "proc(%s:%s/%ld-%ld).\n",
+ "proc('%s:%s'/%ld-%ld).\n",
entry->MR_sle_user.MR_user_decl_module,
entry->MR_sle_user.MR_user_name,
(long) entry->MR_sle_user.MR_user_arity,
@@ -920,16 +953,15 @@
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",
+ MR_send_message_to_socket_format(
+ "def_module(\"%s\").\n",
entry->MR_sle_user.MR_user_def_module);
}
}
- MR_send_message_to_socket_format( "%s.\n",
+ MR_send_message_to_socket_format("det(\"%s\").\n",
MR_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");
}
+
+#endif /* MR_USE_EXTERNAL_DEBUGGER */
Index: trace/mercury_trace_external.h
--- 0.11/trace/mercury_trace_external.h Tue, 16 Feb 1999 17:49:57 +0100 jahier (submitdiff/7_mercury_tr 1.3 640)
+++ 0.11(w)/trace/mercury_trace_external.h Tue, 16 Feb 1999 18:46:35 +0100 jahier (submitdiff/7_mercury_tr 1.3 640)
@@ -17,23 +17,6 @@
Unsigned depth, const char *path, int *max_mr_num);
-/*
-** Use a GNU C extension to enforce static type checking
-** for printf-style functions.
-** (See the "Function attributes" section of "C extensions"
-** chapter of the GNU C manual for detailed documentation.)
-*/
-#ifdef __GNUC__
- #define MR_LIKE_PRINTF(format_argnum, vars_argnum) \
- __attribute__ ((format (printf, (format_argnum), (vars_argnum))))
-#else
- #define MR_LIKE_PRINTF(n, m) /* nothing */
-#endif
-
-void MR_send_message_to_socket_format(const char *format, ...)
- MR_LIKE_PRINTF(1, 2);
-
-
#endif /* MR_USE_EXTERNAL_DEBUGGER */
#endif /* MERCURY_TRACE_EXTERNAL_H */
Index: trace/mercury_trace_internal.c
--- 0.11/trace/mercury_trace_internal.c Tue, 16 Feb 1999 17:49:57 +0100 jahier (submitdiff/10_mercury_tr 1.5 640)
+++ 0.11(w)/trace/mercury_trace_internal.c Tue, 16 Feb 1999 19:15:42 +0100 jahier (submitdiff/10_mercury_tr 1.5 640)
@@ -53,7 +53,6 @@
** XXX We should consider whether all the static variables in this module
** should be thread local.
*/
-
/*
** Debugger I/O streams.
** Replacements for stdin/stdout/stderr respectively.
Index: trace/mercury_trace.h
--- 0.11/trace/mercury_trace.h Tue, 16 Feb 1999 17:49:57 +0100 jahier (submitdiff/11_mercury_tr 1.5 640)
+++ 0.11(w)/trace/mercury_trace.h Tue, 16 Feb 1999 18:34:34 +0100 jahier (submitdiff/11_mercury_tr 1.5 640)
@@ -98,6 +98,12 @@
bool MR_trace_must_check;
} MR_Trace_Cmd_Info;
+/*
+** The different Mercury determinisms are internally represented by integers.
+** This array gives the correspondance with the internal representation and
+** the names that are usually used to denote determinisms.
+*/
+
extern const char * MR_detism_names[];
#define MR_port_is_final(port) ((port) == MR_PORT_EXIT || \
Index: trace/mercury_trace.c
--- 0.11/trace/mercury_trace.c Tue, 16 Feb 1999 17:49:57 +0100 jahier (submitdiff/12_mercury_tr 1.6 640)
+++ 0.11(w)/trace/mercury_trace.c Tue, 16 Feb 1999 18:33:32 +0100 jahier (submitdiff/12_mercury_tr 1.6 640)
@@ -435,7 +435,7 @@
/*
-** The different Mercury determinisms are internaly represented by integers.
+** The different Mercury determinisms are internally represented by integers.
** This array gives the correspondance with the internal representation and
** the names that are usually used to denote determinisms.
*/
*************************************************************************
* diff *
*************************************************************************
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 20:21:51
@@ -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 20:21:56
@@ -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 *print_stack_record(
+ FILE *, const MR_Stack_Layout_Entry *,
+ int, int, Word *, Word *));
+static void MR_dump_stack_record_flush(FILE *fp,
+ void *print_stack_record(
+ 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 *print_stack_record(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,
+ print_stack_record);
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,
+ print_stack_record);
} else {
MR_dump_stack_record_frame(fp, entry_layout,
- NULL, NULL);
+ NULL, NULL, print_stack_record);
}
- MR_dump_stack_record_flush(fp);
+ MR_dump_stack_record_flush(fp,
+ print_stack_record);
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,
+ print_stack_record);
} else {
MR_dump_stack_record_frame(fp, entry_layout,
- NULL, NULL);
+ NULL, NULL, print_stack_record);
}
}
@@ -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, print_stack_record);
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 *print_stack_record(
+ 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, print_stack_record);
prev_entry_layout = entry_layout;
prev_entry_layout_count = 1;
@@ -334,145 +326,13 @@
}
static void
-MR_dump_stack_record_flush(FILE *fp)
+MR_dump_stack_record_flush(FILE *fp, void *print_stack_record(
+ FILE *, const MR_Stack_Layout_Entry *, int, int, Word *, Word *))
{
if (prev_entry_layout != NULL) {
- MR_dump_stack_record_print(fp, prev_entry_layout,
+ print_stack_record(fp, prev_entry_layout,
prev_entry_layout_count, prev_entry_start_level,
prev_entry_base_sp, prev_entry_base_curfr);
}
}
-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 20:21:56
@@ -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 *print_stack_record(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 20:21:57
@@ -432,3 +432,28 @@
*succeeded = FALSE;
return 0;
}
+
+
+/*
+** The different Mercury determinisms are internally represented by integers.
+** This array gives the correspondance with the internal representation and
+** the names that are usually used to denote determinisms.
+*/
+
+extern const char * MR_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 20:21:57
@@ -98,6 +98,14 @@
bool MR_trace_must_check;
} MR_Trace_Cmd_Info;
+/*
+** The different Mercury determinisms are internally represented by integers.
+** This array gives the correspondance with the internal representation and
+** the names that are usually used to denote determinisms.
+*/
+
+extern const char * MR_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 20:21:59
@@ -30,6 +30,7 @@
#include "mercury_layout_util.h"
#include <stdio.h>
#include <errno.h>
+#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
@@ -53,21 +54,38 @@
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 nondet stack */
+ MR_REQUEST_STACK_REGS = 12 /* prints the contents of the virtual
+ machine registers. */
} MR_debugger_request_type;
static MercuryFile MR_debugger_socket_in;
static MercuryFile MR_debugger_socket_out;
+/*
+** Use a GNU C extension to enforce static type checking
+** for printf-style functions.
+** (See the "Function attributes" section of "C extensions"
+** chapter of the GNU C manual for detailed documentation.)
+*/
+#ifdef __GNUC__
+ #define MR_LIKE_PRINTF(format_argnum, vars_argnum) \
+ __attribute__ ((format (printf, (format_argnum), (vars_argnum))))
+#else
+ #define MR_LIKE_PRINTF(n, m) /* nothing */
+#endif
+void MR_send_message_to_socket_format(const char *format, ...)
+ MR_LIKE_PRINTF(1, 2);
+
static void MR_send_message_to_socket(const char *message);
-static void MR_send_message_to_socket_format(const char *format,
- const char *message);
static void MR_read_request_from_socket(
Word *debugger_request_ptr,
Integer *debugger_request_type_ptr);
@@ -90,6 +108,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 +367,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 +468,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(
+ "stack_regs(%lu, %lu, %lu).\n",
+ (unsigned long)
+ MR_saved_sp(saved_regs),
+ (unsigned long)
+ MR_saved_curfr(saved_regs),
+ (unsigned long)
+ MR_saved_maxfr(saved_regs));
+ break;
+
case MR_REQUEST_NO_TRACE:
cmd->MR_trace_cmd = MR_CMD_TO_END;
return jumpaddr;
@@ -581,15 +663,20 @@
return result;
}
-static void
-MR_send_message_to_socket_format(const char *format, const char *message)
+static void
+MR_send_message_to_socket_format(const char *format, ...)
{
- fprintf(MR_debugger_socket_out.file, format, message);
- fflush(MR_debugger_socket_out.file);
- MR_debugger_socket_out.line_number++;
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(MR_debugger_socket_out.file, format, args);
+ va_end(args);
+ fflush(MR_debugger_socket_out.file);
+ MR_debugger_socket_out.line_number++;
}
+
static void
MR_send_message_to_socket(const char *message)
{
@@ -737,4 +824,144 @@
);
return num;
}
+
+/*
+** The protocol between the debugged Mercury program and the external debugger
+** is the following:
+** 1) The debugger sends "stack";
+** 2) For each procedure in the stack that is not generated by the compiler, the
+** debuggee sends:
+** - level(int) (the level of the procedure in the stack)
+** - detail(unsigned long, unsigned long, unsigned long) (the call event
+** number, call sequence number and depth of the goal of the procedure)
+** - the atom 'pred' or 'func' depending if the procedure is a function
+** or not
+** - proc('string:string'/long-long) (the name of the procedure)
+** - det(string) (the determinism of the procedure)
+** - def_module(string) (the name of the defining module if different from
+** the current one)
+**
+** For each compiler generated procedures, the debuggee sends:
+** - level(int) (as above)
+** - detail(unsigned long, unsigned long, unsigned long) (as above)
+** - proc('string for string:string'/long-long) (the name of the
+** compiler-generated procedure)
+** - def_module(string) (as above)
+*/
+
+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("level(%d).\n", start_level);
+ 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(
+ "detail(%lu, %lu, %lu).\n",
+ (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 {
+ MR_send_message_to_socket_format(
+ "detail(%lu, %lu, %lu).\n",
+ (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));
+ }
+ }
+ }
+
+ if (MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry)) {
+ MR_send_message_to_socket_format(
+ "proc('%s for %s:%s'/%ld-%ld).\n",
+ 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)
+ {
+ MR_send_message_to_socket_format(
+ "def_module(\"%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");
+ } else {
+ fatal_error("procedure is not pred or func");
+ }
+
+ MR_send_message_to_socket_format(
+ "proc('%s:%s'/%ld-%ld).\n",
+ 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)
+ {
+ MR_send_message_to_socket_format(
+ "def_module(\"%s\").\n",
+ entry->MR_sle_user.MR_user_def_module);
+ }
+ }
+
+ MR_send_message_to_socket_format("det(\"%s\").\n",
+ MR_detism_names[entry->MR_sle_detism]);
+
+}
+
#endif /* MR_USE_EXTERNAL_DEBUGGER */
Index: trace/mercury_trace_external.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_trace_external.h
--- mercury_trace_external.h 1999/02/10 22:31:24 1.3
+++ mercury_trace_external.h 1999/02/16 20:21:59
@@ -16,6 +16,7 @@
Word *saved_regs, MR_Trace_Port port, Unsigned seqno,
Unsigned depth, const char *path, int *max_mr_num);
+
#endif /* MR_USE_EXTERNAL_DEBUGGER */
#endif /* MERCURY_TRACE_EXTERNAL_H */
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 20:22:02
@@ -53,7 +53,6 @@
** XXX We should consider whether all the static variables in this module
** should be thread local.
*/
-
/*
** Debugger I/O streams.
** Replacements for stdin/stdout/stderr respectively.
@@ -215,6 +214,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 +792,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);
@@ -2460,3 +2464,25 @@
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);
+}
+
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 20:22:02
@@ -48,6 +48,7 @@
MR_Trace_Port port, int seqno, int depth,
const char *path, int *max_mr_num);
+
/*
** Debugger I/O streams.
** Replacements for stdin/stdout/stderr respectively.
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.4
diff -u -r1.4 mercury_trace_tables.c
--- mercury_trace_tables.c 1998/12/17 13:37:17 1.4
+++ mercury_trace_tables.c 1999/02/16 20:22:02
@@ -15,6 +15,7 @@
#include "mercury_label.h"
#include "mercury_array_macros.h"
#include "mercury_trace_tables.h"
+#include "mercury_trace.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
@@ -386,5 +387,118 @@
{
f(data, cur_entry);
}
+ }
+}
+
+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)", MR_detism_names[entry->MR_sle_detism]);
+
+ if (extra != NULL) {
+ fprintf(fp, " %s\n", extra);
+ } else {
+ fprintf(fp, "\n");
}
}
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_trace_tables.h
--- mercury_trace_tables.h 1998/12/17 13:37:19 1.2
+++ mercury_trace_tables.h 1999/02/16 20:22:02
@@ -121,4 +121,20 @@
void f(void *, const MR_Stack_Layout_Entry *),
void *data);
+/*
+** 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 /* not MERCURY_TRACE_TABLES_H */
--
R1.
More information about the developers
mailing list