for review: new debugger command set (part 3 of 4)
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Oct 1 18:49:36 AEST 1998
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/exceptions
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.164
diff -u -u -r1.164 io.m
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
--- io.m 1998/09/19 05:32:46 1.164
+++ io.m 1998/09/21 06:39:19
@@ -1736,11 +1736,15 @@
io__write_float(Stream, F),
io__write_many(Stream, Rest).
+:- pragma export(io__print(in, in, di, uo), "ML_io_print_to_stream").
+
io__print(Stream, Term) -->
io__set_output_stream(Stream, OrigStream),
io__print(Term),
io__set_output_stream(OrigStream, _Stream).
+:- pragma export(io__print(in, di, uo), "ML_io_print_to_cur_stream").
+
io__print(Term) -->
% `string', `char' and `univ' are special cases for io__print
{ type_to_univ(Term, Univ) },
@@ -2833,6 +2837,10 @@
}").
/* stream predicates */
+
+:- pragma export(io__stdin_stream(out, di, uo), "ML_io_stdin_stream").
+:- pragma export(io__stdout_stream(out, di, uo), "ML_io_stdout_stream").
+:- pragma export(io__stderr_stream(out, di, uo), "ML_io_stderr_stream").
:- pragma c_code(io__stdin_stream(Stream::out, IO0::di, IO::uo),
[will_not_call_mercury, thread_safe], "
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.39
diff -u -u -r1.39 Mmakefile
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
--- Mmakefile 1998/09/29 05:10:54 1.39
+++ Mmakefile 1998/09/29 05:53:11
@@ -45,6 +45,7 @@
mercury_imp.h \
mercury_init.h \
mercury_label.h \
+ mercury_layout_util.h \
mercury_library_types.h \
mercury_memory.h \
mercury_memory_zones.h \
@@ -70,7 +71,6 @@
mercury_thread.h \
mercury_timing.h \
mercury_trace_base.h \
- mercury_trace_util.h \
mercury_trail.h \
mercury_types.h \
mercury_type_info.h \
@@ -108,6 +108,7 @@
mercury_heap_profile.c \
mercury_ho_call.c \
mercury_label.c \
+ mercury_layout_util.c \
mercury_memory.c \
mercury_memory_zones.c \
mercury_memory_handlers.c \
@@ -124,7 +125,6 @@
mercury_thread.c \
mercury_timing.c \
mercury_trace_base.c \
- mercury_trace_util.c \
mercury_trail.c \
mercury_type_info.c \
mercury_wrapper.c
Index: runtime/mercury_accurate_gc.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_accurate_gc.c,v
retrieving revision 1.1
diff -u -u -r1.1 mercury_accurate_gc.c
--- mercury_accurate_gc.c 1998/07/22 07:52:21 1.1
+++ mercury_accurate_gc.c 1998/09/29 06:23:51
@@ -12,8 +12,8 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
#ifdef NATIVE_GC
-#include "mercury_trace_util.h"
#include "mercury_deep_copy.h"
+#include "mercury_layout_util.h"
#include "mercury_agc_debug.h"
/*
@@ -144,7 +144,7 @@
DELETE EASY-TO-MISUSE MACROS
/*
** Save the old succip and its location.
*/
- saved_success_location = &based_detstackvar(sp_at_signal,
+ saved_success_location = &MR_based_stackvar(sp_at_signal,
number);
saved_success = (Code *) *saved_success_location;
@@ -292,8 +292,10 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
/* Get the type parameters from the stack frame. */
- type_params = MR_trace_materialize_typeinfos_base(vars,
- top_frame, stack_pointer, current_frame);
+ /* XXX We must pass NULL since the registers have not been saved */
+ /* XXX This is probably a bug; Tyson should look into it */
+ type_params = MR_materialize_typeinfos_base(vars,
+ NULL, stack_pointer, current_frame);
/* Copy each live variable */
@@ -392,8 +394,8 @@
DELETE EASY-TO-MISUSE MACROS
break;
case MR_LVAL_TYPE_STACKVAR:
- based_detstackvar(stack_pointer, locn_num) =
- agc_deep_copy(&based_detstackvar(
+ MR_based_stackvar(stack_pointer, locn_num) =
+ agc_deep_copy(&MR_based_stackvar(
stack_pointer,locn_num),
type_info, MR_ENGINE(heap_zone2->min),
MR_ENGINE(heap_zone2->hardmax));
Index: runtime/mercury_agc_debug.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_agc_debug.c,v
retrieving revision 1.3
diff -u -u -r1.3 mercury_agc_debug.c
--- mercury_agc_debug.c 1998/09/21 13:17:42 1.3
+++ mercury_agc_debug.c 1998/09/22 02:28:12
@@ -9,7 +9,7 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
*/
#include "mercury_imp.h"
-#include "mercury_trace_util.h"
+#include "mercury_layout_util.h"
#include "mercury_deep_copy.h"
#include "mercury_agc_debug.h"
@@ -26,6 +26,8 @@
void
MR_agc_dump_roots(MR_RootList roots)
{
+ Word saved_regs[MAX_FAKE_REG];
+
fflush(NULL);
fprintf(stderr, "Dumping roots\n");
@@ -40,17 +42,19 @@
** the saved registers).
*/
restore_registers();
- MR_copy_regs_to_saved_regs(MAX_REAL_REG + NUM_SPECIAL_REG);
+ MR_copy_regs_to_saved_regs(MAX_REAL_REG + NUM_SPECIAL_REG,
+ saved_regs);
MR_hp = MR_ENGINE(debug_heap_zone->min);
MR_virtual_hp = MR_ENGINE(debug_heap_zone->min);
fflush(NULL);
- MR_trace_write_variable((Word) roots->type_info, *roots->root);
+ MR_write_variable((Word) roots->type_info, *roots->root);
fflush(NULL);
fprintf(stderr, "\n");
- MR_copy_saved_regs_to_regs(MAX_REAL_REG + NUM_SPECIAL_REG);
+ MR_copy_saved_regs_to_regs(MAX_REAL_REG + NUM_SPECIAL_REG,
+ saved_regs);
save_registers();
roots = roots->next;
}
@@ -61,6 +65,7 @@
MR_agc_dump_stack_frames(MR_Internal *label, MemoryZone *heap_zone,
Word *stack_pointer, Word *current_frame)
{
+ Word saved_regs[MAX_FAKE_REG];
int i, var_count;
const MR_Stack_Layout_Vars *vars;
Word *type_params, type_info, value;
@@ -87,8 +92,8 @@
var_count = layout->MR_sll_var_count;
vars = &(layout->MR_sll_var_info);
- type_params = MR_trace_materialize_typeinfos_base(vars,
- top_frame, stack_pointer, current_frame);
+ type_params = MR_materialize_typeinfos_base(vars,
+ NULL, stack_pointer, current_frame);
for (i = 0; i < var_count; i++) {
MR_Stack_Layout_Var sl_var;
@@ -114,22 +119,22 @@
*/
restore_registers();
MR_copy_regs_to_saved_regs(MAX_REAL_REG +
- NUM_SPECIAL_REG);
+ NUM_SPECIAL_REG, saved_regs);
MR_hp = MR_ENGINE(debug_heap_zone->min);
MR_virtual_hp = MR_ENGINE(debug_heap_zone->min);
- if (MR_trace_get_type_and_value_base(&sl_var,
- top_frame, stack_pointer,
+ if (MR_get_type_and_value_base(&sl_var,
+ NULL, stack_pointer,
current_frame, type_params,
&type_info, &value)) {
printf("\t");
- MR_trace_write_variable(type_info, value);
+ MR_write_variable(type_info, value);
printf("\n");
}
MR_copy_saved_regs_to_regs(MAX_REAL_REG +
- NUM_SPECIAL_REG);
+ NUM_SPECIAL_REG, saved_regs);
save_registers();
#endif /* MR_DEBUG_AGC_PRINT_VARS */
@@ -154,7 +159,7 @@
DELETE EASY-TO-MISUSE MACROS
}
success_ip = (Code *)
- based_detstackvar(stack_pointer, number);
+ MR_based_stackvar(stack_pointer, number);
stack_pointer = stack_pointer -
entry_layout->MR_sle_stack_slots;
label = MR_lookup_internal_by_addr(success_ip);
@@ -191,7 +196,7 @@
break;
case MR_LVAL_TYPE_STACKVAR:
- value = based_detstackvar(stack_pointer, locn_num);
+ value = MR_based_stackvar(stack_pointer, locn_num);
have_value = TRUE;
fprintf(stderr, "stackvar%d", locn_num);
break;
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.10
diff -u -u -r1.10 mercury_conf_param.h
--- mercury_conf_param.h 1998/09/15 09:55:22 1.10
+++ mercury_conf_param.h 1998/09/18 07:56:45
@@ -187,6 +187,14 @@
ADD TRACE DEPTH HISTOGRAMS
** Enables profiling of memory usage.
*/
+/*
+** Experimental options:
+**
+** MR_TRACE_HISTOGRAM
+** Enable this if you want to count the number of execution tracing events
+** at various call depths.
+*/
+
/*---------------------------------------------------------------------------*/
/*
** Settings of configuration parameters which can be passed on
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.7
diff -u -u -r1.7 mercury_init.h
--- mercury_init.h 1998/09/29 05:10:56 1.7
+++ mercury_init.h 1998/09/29 06:39:02
@@ -92,40 +92,59 @@
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
/*
** mercury_main() takes the address of the following predicates/functions,
** which are defined elsewhere.
+**
+** These declarations duplicate some of the contents of the automatically
+** generated header files for some of the library modules, and therefore
+** represent a potential double maintenance problem. At the moment we
+** accept this because it avoids having the runtime rely on the library.
+** However, the dependence on browser/debugger_interface.m is unnecessary,
+** since the only code that relies on the ML_DI_* variables below is
+** in the trace directory, which is allowed to rely on the browser
+** directory.
*/
-Declare_entry(mercury__main_2_0); /* in the user's program */
-extern void mercury_init_io(void); /* in the Mercury library */
-extern void ML_io_init_state(void); /* in the Mercury library */
-extern void ML_io_finalize_state(void); /* in the Mercury library */
-
-
-/* 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) */
-Integer ML_DI_get_var_number(Word);
-void ML_DI_read_request_from_socket(Word, Word *, Integer *);
+/* in the user's program */
+Declare_entry(mercury__main_2_0);
+
+/* in library/io.h */
+extern void mercury_init_io(void);
+extern void ML_io_init_state(void);
+extern void ML_io_finalize_state(void);
+extern void ML_io_stderr_stream(Word *);
+extern void ML_io_stdout_stream(Word *);
+extern void ML_io_stdin_stream(Word *);
+extern void ML_io_print_to_cur_stream(Word, Word);
+extern void ML_io_print_to_stream(Word, Word, Word);
+
+/* in browser/debugger_interface.h */
+extern void ML_DI_output_current_vars(Word, Word, Word);
+ /* output_current_vars/4 */
+extern void ML_DI_output_current_nth_var(Word, Word);
+ /* output_current_nth_var/3 */
+extern void ML_DI_output_current_live_var_names(Word, Word, Word);
+ /* output_current_live_var_names/5 */
+extern void ML_DI_output_current_slots(Integer, Integer, Integer, Word,
+ String, String, Integer, Integer, Integer, String, Word);
+ /* output_current_slots/13 */
+extern bool ML_DI_found_match(Integer, Integer, Integer, Word, String,
+ String, Integer, Integer, Integer, Word, String, Word);
+ /* found_match/12 */
+extern Integer ML_DI_get_var_number(Word);
+extern void ML_DI_read_request_from_socket(Word, Word *, Integer *);
+
/* in library/std_util.m */
-String ML_type_name(Word);
+extern String ML_type_name(Word);
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
/* in runtime/mercury_trace_base.c */
-void MR_trace_fake(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int);
+extern Code *MR_trace_fake(const MR_Stack_Layout_Label *, MR_Trace_Port,
+ Unsigned, Unsigned, const char *, int);
/* in trace/mercury_trace.c */
-void MR_trace_real(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int);
+extern Code *MR_trace_real(const MR_Stack_Layout_Label *, MR_Trace_Port,
+ Unsigned, Unsigned, const char *, int);
+
+/* in library/std_util.h */
+extern String ML_type_name(Word);
#endif /* not MERCURY_INIT_H */
--- mercury_trace_util.c.was Tue Sep 22 12:08:31 1998
+++ mercury_layout_util.c Tue Sep 22 16:51:58 1998
@@ -13,31 +13,24 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
#include "mercury_imp.h"
#include "mercury_stack_layout.h"
-#include "mercury_trace_util.h"
-
-Word MR_saved_regs[MAX_FAKE_REG];
+#include "mercury_layout_util.h"
void
-MR_copy_regs_to_saved_regs(int max_mr_num)
+MR_copy_regs_to_saved_regs(int max_mr_num, Word *saved_regs)
{
/*
- ** In the process of browsing, we call Mercury code,
+ ** In the process of browsing within the debugger, we call Mercury,
** which may clobber the contents of the virtual machine registers,
** both control and general purpose, and both real and virtual
** registers. We must therefore save and restore these.
- ** We store them in the MR_saved_regs array.
+ ** We store them in the saved_regs array.
**
** The call to MR_trace will clobber the transient registers
** on architectures that have them. The compiler generated code
** will therefore call save_transient_registers to save the transient
** registers in the fake_reg array. We here restore them to the
** real registers, save them with the other registers back in
- ** fake_reg, and then copy all fake_reg entries to MR_saved_regs.
- **
- ** If any code invoked by MR_trace is itself traced,
- ** MR_saved_regs will be overwritten, leading to a crash later on.
- ** This is one reason (but not the only one) why we turn off
- ** tracing when we call back Mercury code from this file.
+ ** fake_reg, and then copy all fake_reg entries to saved_regs.
*/
int i;
@@ -46,12 +39,12 @@
save_registers();
for (i = 0; i <= max_mr_num; i++) {
- MR_saved_regs[i] = MR_fake_reg[i];
+ saved_regs[i] = MR_fake_reg[i];
}
}
void
-MR_copy_saved_regs_to_regs(int max_mr_num)
+MR_copy_saved_regs_to_regs(int max_mr_num, Word *saved_regs)
{
/*
** We execute the converse procedure to MR_copy_regs_to_saved_regs.
@@ -63,7 +56,7 @@
int i;
for (i = 0; i <= max_mr_num; i++) {
- MR_fake_reg[i] = MR_saved_regs[i];
+ MR_fake_reg[i] = saved_regs[i];
}
restore_registers();
@@ -71,15 +64,16 @@
}
Word *
-MR_trace_materialize_typeinfos(const MR_Stack_Layout_Vars *vars)
+MR_materialize_typeinfos(const MR_Stack_Layout_Vars *vars,
+ Word *saved_regs)
{
- return MR_trace_materialize_typeinfos_base(vars, TRUE,
- MR_saved_sp(MR_saved_regs), MR_saved_curfr(MR_saved_regs));
+ return MR_materialize_typeinfos_base(vars, saved_regs,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs));
}
Word *
-MR_trace_materialize_typeinfos_base(const MR_Stack_Layout_Vars *vars,
- bool saved_regs_valid, Word *base_sp, Word *base_curfr)
+MR_materialize_typeinfos_base(const MR_Stack_Layout_Vars *vars,
+ Word *saved_regs, Word *base_sp, Word *base_curfr)
{
Word *type_params;
bool succeeded;
@@ -96,12 +90,12 @@
*/
for (i = 1; i <= count; i++) {
if (vars->MR_slvs_tvars[i] != 0) {
- type_params[i] = MR_trace_lookup_live_lval_base(
+ type_params[i] = MR_lookup_live_lval_base(
vars->MR_slvs_tvars[i],
- saved_regs_valid, base_sp, base_curfr,
+ saved_regs, base_sp, base_curfr,
&succeeded);
- if (!succeeded) {
- fatal_error("missing type param in MR_trace_materialize_typeinfos_base");
+ if (! succeeded) {
+ fatal_error("missing type param in MR_materialize_typeinfos_base");
}
}
}
@@ -113,7 +107,7 @@
}
Word
-MR_trace_make_var_list(const MR_Stack_Layout_Label *layout)
+MR_make_var_list(const MR_Stack_Layout_Label *layout, Word *saved_regs)
{
int var_count;
const MR_Stack_Layout_Vars *vars;
@@ -151,8 +145,8 @@
** at the moment due to the lack of a true browser.
*/
- if (!MR_trace_get_type_and_value_filtered(var, name,
- &type_info, &value))
+ if (! MR_get_type_and_value_filtered(var, saved_regs,
+ name, &type_info, &value))
{
continue;
}
@@ -162,7 +156,7 @@
** and cons it onto the list.
** Note that the calls to save/restore transient registers
** can't be hoisted out of the loop, because
- ** MR_trace_get_type_and_value() calls MR_create_type_info()
+ ** MR_get_type_and_value() calls MR_create_type_info()
** which may allocate memory using incr_saved_hp.
*/
@@ -178,19 +172,29 @@
return univ_list;
}
+int
+MR_get_register_number(MR_Live_Lval locn)
+{
+ if (MR_LIVE_LVAL_TYPE(locn) == MR_LVAL_TYPE_R) {
+ return MR_LIVE_LVAL_NUMBER(locn);
+ } else {
+ return -1;
+ }
+}
+
/* if you want to debug this code, you may want to set this var to TRUE */
-static bool MR_trace_print_locn = FALSE;
+static bool MR_print_locn = FALSE;
Word
-MR_trace_lookup_live_lval(MR_Live_Lval locn, bool *succeeded)
+MR_lookup_live_lval(MR_Live_Lval locn, Word *saved_regs, bool *succeeded)
{
- return MR_trace_lookup_live_lval_base(locn, TRUE,
- MR_saved_sp(MR_saved_regs), MR_saved_curfr(MR_saved_regs),
+ return MR_lookup_live_lval_base(locn, saved_regs,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
succeeded);
}
Word
-MR_trace_lookup_live_lval_base(MR_Live_Lval locn, bool saved_regs_valid,
+MR_lookup_live_lval_base(MR_Live_Lval locn, Word *saved_regs,
Word *base_sp, Word *base_curfr, bool *succeeded)
{
int locn_num;
@@ -202,75 +206,75 @@
locn_num = (int) MR_LIVE_LVAL_NUMBER(locn);
switch (MR_LIVE_LVAL_TYPE(locn)) {
case MR_LVAL_TYPE_R:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("r%d", locn_num);
}
- if (saved_regs_valid) {
- value = saved_reg(MR_saved_regs, locn_num);
+ if (saved_regs != NULL) {
+ value = saved_reg(saved_regs, locn_num);
*succeeded = TRUE;
}
break;
case MR_LVAL_TYPE_F:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("f%d", locn_num);
}
break;
case MR_LVAL_TYPE_STACKVAR:
DELETE EASY-TO-MISUSE MACROS
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("stackvar%d", locn_num);
}
- value = based_detstackvar(base_sp, locn_num);
+ value = MR_based_stackvar(base_sp, locn_num);
*succeeded = TRUE;
break;
case MR_LVAL_TYPE_FRAMEVAR:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("framevar%d", locn_num);
}
- value = based_framevar(base_curfr, locn_num);
+ value = MR_based_framevar(base_curfr, locn_num);
*succeeded = TRUE;
break;
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
case MR_LVAL_TYPE_SUCCIP:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("succip");
}
break;
case MR_LVAL_TYPE_MAXFR:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("maxfr");
}
break;
case MR_LVAL_TYPE_CURFR:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("curfr");
}
break;
case MR_LVAL_TYPE_HP:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("hp");
}
break;
case MR_LVAL_TYPE_SP:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("sp");
}
break;
case MR_LVAL_TYPE_UNKNOWN:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("unknown");
}
break;
default:
- if (MR_trace_print_locn) {
+ if (MR_print_locn) {
printf("DEFAULT");
}
break;
@@ -280,17 +284,17 @@
}
bool
-MR_trace_get_type_and_value(const MR_Stack_Layout_Var *var,
- Word *type_params, Word *type_info, Word *value)
+MR_get_type_and_value(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *type_params, Word *type_info, Word *value)
{
- return MR_trace_get_type_and_value_base(var, TRUE,
- MR_saved_sp(MR_saved_regs), MR_saved_curfr(MR_saved_regs),
+ return MR_get_type_and_value_base(var, saved_regs,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
type_params, type_info, value);
}
bool
-MR_trace_get_type_and_value_base(const MR_Stack_Layout_Var *var,
- bool saved_regs_valid, Word *base_sp, Word *base_curfr,
+MR_get_type_and_value_base(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *base_sp, Word *base_curfr,
Word *type_params, Word *type_info, Word *value)
{
bool succeeded;
@@ -303,23 +307,23 @@
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);
- *value = MR_trace_lookup_live_lval_base(var->MR_slv_locn,
- saved_regs_valid, base_sp, base_curfr, &succeeded);
+ *value = MR_lookup_live_lval_base(var->MR_slv_locn,
+ saved_regs, base_sp, base_curfr, &succeeded);
return succeeded;
}
bool
-MR_trace_get_type(const MR_Stack_Layout_Var *var,
+MR_get_type(const MR_Stack_Layout_Var *var, Word *saved_regs,
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),
+ return MR_get_type_base(var, saved_regs,
+ MR_saved_sp(saved_regs), MR_saved_curfr(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,
+MR_get_type_base(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *base_sp, Word *base_curfr,
Word *type_params, Word *type_info)
{
bool succeeded;
@@ -336,35 +340,6 @@
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
return TRUE;
}
-void
-MR_trace_write_variable(Word type_info, Word value)
-{
-
- /*
- ** XXX It would be nice if we could call an exported C function
- ** version of the browser predicate, and thus avoid going
- ** through call_engine, but for some unknown reason, that seemed
- ** to cause the Mercury code in the browser to clobber part of
- ** the C stack.
- **
- ** Probably that was due to a bug which has since been fixed, so
- ** we should change the code below back again...
- **
- ** call_engine() expects the transient registers to be in
- ** fake_reg, others in their normal homes. That is the case on
- ** entry to this function. But r1 or r2 may be transient, so we
- ** need to save/restore transient regs around the assignments to
- ** them.
- */
-
- restore_transient_registers();
- r1 = type_info;
- r2 = value;
- save_transient_registers();
- call_engine(MR_library_trace_browser);
-}
-
-
/*
** get_type_and_value() and get_type() will succeed to retrieve "variables"
** that we do not want to send to the user; "variables" beginning with
@@ -377,23 +352,32 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
*/
bool
-MR_trace_get_type_and_value_filtered(const MR_Stack_Layout_Var *var,
- const char *name,
- Word *type_info, Word *value)
+MR_get_type_and_value_filtered(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, const char *name, Word *type_info, Word *value)
{
return ((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));
+ && MR_get_type_and_value(var, saved_regs, NULL,
+ type_info, value));
}
bool
-MR_trace_get_type_filtered(const MR_Stack_Layout_Var *var,
- const char *name, Word *type_info)
+MR_get_type_filtered(const MR_Stack_Layout_Var *var, Word *saved_regs,
+ const char *name, Word *type_info)
{
return ((strncmp(name, "TypeInfo", 8) != 0)
&& (strncmp(name, "ModuleInfo", 10) != 0)
&& (strncmp(name, "HLDS", 4) != 0)
- && MR_trace_get_type(var, NULL, type_info));
+ && MR_get_type(var, saved_regs, NULL, type_info));
+}
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
+
+void
+MR_write_variable(Word type_info, Word value)
+{
+ Word stdout_stream;
+
+ (*MR_io_stdout_stream)(&stdout_stream);
+ (*MR_io_print_to_stream)(type_info, stdout_stream, value);
}
--- mercury_trace_util.h.was Tue Sep 22 12:08:31 1998
+++ mercury_layout_util.h Tue Sep 22 11:59:38 1998
@@ -4,45 +4,124 @@
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
-#ifndef MERCURY_TRACE_UTIL_H
-#define MERCURY_TRACE_UTIL_H
+#ifndef MERCURY_LAYOUT_UTIL_H
+#define MERCURY_LAYOUT_UTIL_H
-extern Word MR_saved_regs[MAX_FAKE_REG];
-extern void MR_copy_regs_to_saved_regs(int max_mr_num);
-extern void MR_copy_saved_regs_to_regs(int max_mr_num);
-
-extern Word *MR_trace_materialize_typeinfos(const MR_Stack_Layout_Vars
- *vars);
-extern Word *MR_trace_materialize_typeinfos_base(const MR_Stack_Layout_Vars
- *vars, bool saved_regs_valid,
+/*
+** These two functions copy the register state to and from the provided
+** saved_regs array, which should have room for MAX_FAKE_REG Words.
+*/
+
+extern void MR_copy_regs_to_saved_regs(int max_mr_num, Word *saved_regs);
+extern void MR_copy_saved_regs_to_regs(int max_mr_num, Word *saved_regs);
+
+/*
+** A MR_Stack_Layout_Vars describes the variables that are live at a given
+** program point. Some of the types of these variables may contain type
+** variables. Since the values of those type variables are not known until
+** runtime, the MR_Stack_Layout_Vars cannot include full typeinfos for the
+** variables. Instead, it contains pseudo-typeinfos, in which some parts
+** of some typeinfo structures may contain an indication "this data is
+** not available at compile time, but at runtime it will be in this location".
+**
+** MR_materialize_typeinfos takes as input a MR_Stack_Layout_Vars
+** structure. It returns a vector of typeinfos which has one entry for each
+** pseudo-typeinfo in the MR_Stack_Layout_Vars structure, with this typeinfo
+** being the pseudo-typeinfo with the runtime-only information substituted in.
+** Since type variable numbers start at one, the element of this array at
+** index zero will be unused. This means that the array will itself look
+** like a typeinfo.
+**
+** The vector returned by MR_materialize_typeinfos is from malloc;
+** it should be freed after last use.
+**
+** MR_materialize_typeinfos looks up locations in the current
+** environment, as indicated by the set of saved registers (including MR_sp
+** and MR_curfr). MR_materialize_typeinfos_base does the same job but
+** assumes the environment is given by the given values of MR_sp and MR_curfr,
+** and does not assume that the registers have valid contents unless saved_regs
+** is non-null.
+*/
+
+extern Word *MR_materialize_typeinfos(
+ const MR_Stack_Layout_Vars *vars, Word *saved_regs);
+extern Word *MR_materialize_typeinfos_base(
+ const MR_Stack_Layout_Vars *vars, Word *saved_regs,
Word *base_sp, Word *base_curfr);
-extern Word MR_trace_make_var_list(const MR_Stack_Layout_Label *layout);
-extern Word MR_trace_lookup_live_lval(MR_Live_Lval locn, bool *succeeded);
-extern Word MR_trace_lookup_live_lval_base(MR_Live_Lval locn,
- bool saved_regs_valid, Word *base_sp, Word *base_curfr,
+extern Word MR_make_var_list(const MR_Stack_Layout_Label *layout,
+ Word *saved_regs);
+
+/*
+** If the given encoded location refers to a register, return its number.
+** If it does not, return -1.
+*/
+
+extern int MR_get_register_number(MR_Live_Lval locn);
+
+/*
+** Given an encoded location, return the value at that location if possible.
+** *succeeded will say whether the attempt was successful.
+**
+** MR_lookup_live_lval looks up locations in the current environment,
+** as indicated by the set of saved registers (including MR_sp and MR_curfr).
+** MR_lookup_live_lval_base does the same job but assumes the environment
+** is given by the given values of MR_sp and MR_curfr, and does not assume
+** that the registers have valid contents unless saved_regs is non-null.
+*/
+
+extern Word MR_lookup_live_lval(MR_Live_Lval locn,
+ Word *saved_regs, bool *succeeded);
+extern Word MR_lookup_live_lval_base(MR_Live_Lval locn,
+ Word *saved_regs, Word *base_sp, Word *base_curfr,
bool *succeeded);
-extern bool MR_trace_get_type_and_value(const MR_Stack_Layout_Var *var,
- Word *type_params, Word *type_info, Word *value);
-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,
+
+/*
+** Given information about the location of a variable (var) and a vector giving
+** the typeinfos corresponding to the type variables that may occur in
+** the type of that variable (type_params), try to return the value of the
+** variable in *value and the typeinfo describing its type in *type_info.
+** *succeeded will say whether the attempt was successful.
+**
+** The type_params array should have the same format as the array returned
+** by MR_materialize_typeinfos.
+**
+** MR_get_type_and_value looks up locations in the current environment,
+** as indicated by the set of saved registers (including MR_sp and MR_curfr).
+** MR_get_type_and_value_base does the same job but assumes the
+** environment is given by the given values of MR_sp and MR_curfr, and does
+** not assume that the registers have valid contents unless saved_regs is
+** non-null.
+**
+** MR_get_type and MR_get_type_base are similar but do not
+** return the value, whereas the functions with _filtered deliberately
+** do not suceed if the variable's name indicates that the value is likely
+** to be too big. This is a temporary measure only, until we get a better
+** term printer.
+*/
+
+extern bool MR_get_type_and_value(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *type_params, Word *type_info,
+ Word *value);
+extern bool MR_get_type_and_value_base(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, 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,
+extern bool MR_get_type(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *type_params, Word *type_info);
+extern bool MR_get_type_base(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, Word *base_sp, Word *base_curfr,
Word *type_params, Word *type_info);
-extern bool MR_trace_get_type_and_value_filtered(
- const MR_Stack_Layout_Var *var, const char *name,
- Word *type_info, Word *value);
-extern bool MR_trace_get_type_filtered(const MR_Stack_Layout_Var *var,
- const char *name, Word *type_info);
-
+extern bool MR_get_type_and_value_filtered(
+ const MR_Stack_Layout_Var *var, Word *saved_regs,
+ const char *name, Word *type_info, Word *value);
+extern bool MR_get_type_filtered(const MR_Stack_Layout_Var *var,
+ Word *saved_regs, const char *name, Word *type_info);
/*
-** MR_trace_write_variable:
+** MR_write_variable:
** Write a variable to stdout.
*/
-extern void MR_trace_write_variable(Word type_info, Word value);
-#endif /* MERCURY_TRACE_UTIL_H */
+extern void MR_write_variable(Word type_info, Word value);
+
+#endif /* MERCURY_LAYOUT_UTIL_H */
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.8
diff -u -u -r1.8 mercury_stack_layout.h
--- mercury_stack_layout.h 1998/07/09 04:37:57 1.8
+++ mercury_stack_layout.h 1998/09/29 07:28:06
@@ -9,7 +9,7 @@
/*
** mercury_stack_layout.h -
-** Definitions for the stack layout data structures.
+** Definitions for the stack layout data structures.
**
** NOTE: The constants and data-structures used here need to be kept in
** sync with the ones generated in the compiler. If you change anything here,
@@ -70,7 +70,7 @@
** - stack slots, registers, and special lvals such as succip, hp,
** etc.
**
-** MR_Live_Lval is encoded using an 8 bit low tag, the rest of the word is a
+** MR_Live_Lval is encoded using an 8 bit low tag, the rest of the word is a
** data field describing which stack slot number or register number.
**
** Lval Tag Rest
@@ -93,7 +93,7 @@
typedef Word MR_Live_Lval;
-typedef enum {
+typedef enum {
MR_LVAL_TYPE_R,
MR_LVAL_TYPE_F,
MR_LVAL_TYPE_STACKVAR,
@@ -103,7 +103,7 @@
MR_LVAL_TYPE_CURFR,
MR_LVAL_TYPE_HP,
MR_LVAL_TYPE_SP,
- MR_LVAL_TYPE_UNKNOWN
+ MR_LVAL_TYPE_UNKNOWN
} MR_Lval_Type;
#define MR_LIVE_LVAL_TAGBITS 8
@@ -126,7 +126,7 @@
**
** The data is encoded such that low values (less than
** TYPELAYOUT_MAX_VARINT) represent succip, hp, etc. Higher values
-** represent data variables, and are pointers to a 2 word cell,
+** represent data variables, and are pointers to a 2 word cell,
** containing a pseudo type_info and an instantiation represention.
**
** This data is generated in compiler/stack_layout.m, which must be kept
@@ -135,16 +135,16 @@
typedef Word MR_Live_Type;
-typedef enum {
+typedef enum {
MR_LIVE_TYPE_SUCCIP,
MR_LIVE_TYPE_HP,
MR_LIVE_TYPE_CURFR,
MR_LIVE_TYPE_MAXFR,
MR_LIVE_TYPE_REDOIP,
- MR_LIVE_TYPE_UNWANTED
+ MR_LIVE_TYPE_UNWANTED
} MR_Lval_NonVar;
-typedef struct {
+typedef struct {
Word *pseudo_type_info;
Word inst; /* not yet used; currently always -1 */
} MR_Var_Shape_Info;
@@ -189,12 +189,18 @@
SUPPORT RETRY
MR_Live_Lval *MR_slvs_tvars;
} MR_Stack_Layout_Vars;
-#define MR_name_if_present(vars, i) \
- ((vars->MR_slvs_names != NULL \
- && vars->MR_slvs_names[(i)] != NULL) \
- ? vars->MR_slvs_names[(i)] \
+#define MR_name_if_present(vars, i) \
+ ((vars->MR_slvs_names != NULL \
+ && vars->MR_slvs_names[(i)] != NULL) \
+ ? strchr(vars->MR_slvs_names[(i)], ':') + 1 \
: "")
+#define MR_numbered_name_if_present(vars, i) \
+ ((vars->MR_slvs_names != NULL \
+ && vars->MR_slvs_names[(i)] != NULL) \
+ ? vars->MR_slvs_names[(i)] \
+ : "")
+
/*-------------------------------------------------------------------------*/
/*
** Definitions for MR_Stack_Layout_Entry
@@ -222,6 +228,10 @@
USE FIXED STACK SLOTS FOR TRACE INFO
** if MR_ENTRY_LAYOUT_HAS_PROC_ID(entry) evaluates to true.
** Group (3) is present and meaningful
** if MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry) evaluates to true.
+**
+** Group (2) fields have a different interpretation if the procedure is
+** compiler-generated. You can test for this via the macro
+** MR_ENTRY_LAYOUT_COMPILER_GENERATED.
*/
typedef struct MR_Stack_Layout_Entry_Struct {
@@ -242,6 +252,7 @@
/* exec trace group */
struct MR_Stack_Layout_Label_Struct
*MR_sle_call_label;
+ int MR_sle_maybe_from_full;
} MR_Stack_Layout_Entry;
#define MR_ENTRY_LAYOUT_HAS_PROC_ID(entry) \
@@ -251,6 +262,9 @@
(MR_ENTRY_LAYOUT_HAS_PROC_ID(entry) \
&& entry->MR_sle_call_label != NULL)
+#define MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry) \
+ ((int) entry->MR_sle_pred_or_func > MR_FUNCTION)
+
/*
** Define a stack layout for a label that you know very little about.
** It is just a generic entry label, no useful information, except
@@ -275,6 +289,44 @@
#else
#define MR_MAKE_STACK_LAYOUT_ENTRY(l)
#endif /* MR_USE_STACK_LAYOUTS */
+
+/*
+** In procedures compiled with execution tracing, three items are stored
+** in stack slots with fixed numbers. They are:
+**
+** the event number of the call event,
+** the call number, and
+** the call depth.
+**
+** The following macros will access them. They can be used whenever
+** MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry) is true; which set you should use
+** depends on the determinism of the procedure.
+**
+** These macros have to be kept in sync with compiler/trace.m.
+*/
+
+#define MR_event_num_framevar(base_curfr) MR_based_framevar(base_curfr, 1)
+#define MR_call_num_framevar(base_curfr) MR_based_framevar(base_curfr, 2)
+#define MR_call_depth_framevar(base_curfr) MR_based_framevar(base_curfr, 3)
+
+#define MR_event_num_stackvar(base_sp) MR_based_stackvar(base_sp, 1)
+#define MR_call_num_stackvar(base_sp) MR_based_stackvar(base_sp, 2)
+#define MR_call_depth_stackvar(base_sp) MR_based_stackvar(base_sp, 3)
+
+/*
+** In model_non procedures compiled with an execution trace options that
+** require REDO events, one other item is stored in a fixed stack slot.
+** This is
+**
+** the address of the layout structure for the redo event
+**
+** The following macro will access it. This macro should be used only from
+** within the code that calls MR_trace for the REDO event.
+**
+** This macros have to be kept in sync with compiler/trace.m.
+*/
+
+#define MR_redo_layout_framevar(base_curfr) MR_based_framevar(base_curfr, 4)
/*-------------------------------------------------------------------------*/
/*
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.17
diff -u -u -r1.17 mercury_stack_trace.c
--- mercury_stack_trace.c 1998/09/21 06:30:47 1.17
+++ mercury_stack_trace.c 1998/09/21 06:40:15
@@ -171,7 +171,8 @@
return STEP_ERROR_AFTER;
}
- success = (Code *) field(0, *stack_trace_sp_ptr, -number);
+ success = (Code *) MR_based_stackvar(*stack_trace_sp_ptr,
+ number);
*stack_trace_sp_ptr = *stack_trace_sp_ptr -
entry_layout->MR_sle_stack_slots;
} else {
@@ -289,15 +290,42 @@
fprintf(fp, "%9d ", start_level);
if (count > 1) {
- fprintf(fp, " %3d*", count);
+ fprintf(fp, " %3d* ", count);
} else {
- fprintf(fp, "%5s", "");
+ fprintf(fp, "%5s ", "");
}
- fprintf(fp, " %s:%s/%ld-%ld (%s)\n",
+ MR_print_proc_id(fp, entry_layout, NULL);
+}
+
+void
+MR_print_proc_id_for_debugger(const MR_Stack_Layout_Entry *entry_layout)
+{
+ MR_print_proc_id(stdout, entry_layout, NULL);
+}
+
+void
+MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
+ const char *extra)
+{
+ /*
+ ** The following should be a full identification of the procedure
+ ** provided (a) there was no intermodule optimization and (b) we are
+ ** not interested in the details of compiler-generated procedures.
+ */
+
+ fprintf(fp, "%s %s:%s/%ld-%ld (%s)",
+ entry_layout->MR_sle_pred_or_func == MR_PREDICATE ?
+ "pred" : "func",
entry_layout->MR_sle_def_module,
entry_layout->MR_sle_name,
(long) entry_layout->MR_sle_arity,
(long) entry_layout->MR_sle_mode,
detism_names[entry_layout->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.9
diff -u -u -r1.9 mercury_stack_trace.h
--- mercury_stack_trace.h 1998/07/22 07:53:09 1.9
+++ mercury_stack_trace.h 1998/07/23 06:39:41
@@ -37,9 +37,8 @@
** using `:- external'.
*/
-extern void MR_dump_stack(Code *success_pointer,
- Word *det_stack_pointer,
- Word *current_frame);
+extern void MR_dump_stack(Code *success_pointer, Word *det_stack_pointer,
+ Word *current_frame);
/*
** MR_dump_stack_from_layout:
@@ -62,8 +61,7 @@
** The value of maxfr should be in *base_maxfr.
*/
-extern void MR_dump_nondet_stack_from_layout(FILE *fp,
- Word *base_maxfr);
+extern void MR_dump_nondet_stack_from_layout(FILE *fp, Word *base_maxfr);
/*
** MR_find_nth_ancestor:
@@ -81,36 +79,11 @@
*/
extern const MR_Stack_Layout_Label *MR_find_nth_ancestor(
- const MR_Stack_Layout_Label *label_layout,
- int ancestor_level, Word **stack_trace_sp,
- Word **stack_trace_curfr, const char **problem);
+ const MR_Stack_Layout_Label *label_layout,
+ int ancestor_level, Word **stack_trace_sp,
+ Word **stack_trace_curfr, const char **problem);
/*
-** MR_stack_trace_bottom should be set to the address of global_success,
-** the label main/2 goes to on success. Stack dumps terminate when they
-** reach a stack frame whose saved succip slot contains this address.
-*/
-
-Code *MR_stack_trace_bottom;
-
-/*
-** MR_nondet_stack_trace_bottom should be set to the address of the buffer
-** nondet stack frame created before calling main. Nondet stack dumps terminate
-** when they reach a stack frame whose redoip contains this address. Note that
-** the redoip and redofr slots of this frame may be hijacked.
-*/
-
-Word *MR_nondet_stack_trace_bottom;
-
-
-typedef enum {
- STEP_ERROR_BEFORE, /* the current entry_layout has no valid info */
- STEP_ERROR_AFTER, /* the current entry_layout has valid info,
- but the next one does not */
- STEP_OK /* both have valid info */
-} MR_Stack_Walk_Step_Result;
-
-/*
** MR_stack_walk_step:
** This function takes the entry_layout for the current stack
** frame (which is the topmost stack frame from the two stack
@@ -126,10 +99,47 @@
** encountered, problem_ptr will be set to a string representation
** of the error.
*/
+
+typedef enum {
+ STEP_ERROR_BEFORE, /* the current entry_layout has no valid info */
+ STEP_ERROR_AFTER, /* the current entry_layout has valid info,
+ but the next one does not */
+ STEP_OK /* both have valid info */
+} MR_Stack_Walk_Step_Result;
+
extern MR_Stack_Walk_Step_Result
MR_stack_walk_step(const MR_Stack_Layout_Entry *entry_layout,
const MR_Stack_Layout_Label **return_label_layout,
Word **stack_trace_sp_ptr, Word **stack_trace_curfr_ptr,
const char **problem_ptr);
+
+/*
+** MR_stack_trace_bottom should be set to the address of global_success,
+** the label main/2 goes to on success. Stack dumps terminate when they
+** reach a stack frame whose saved succip slot contains this address.
+*/
+
+Code *MR_stack_trace_bottom;
+
+/*
+** MR_nondet_stack_trace_bottom should be set to the address of the buffer
+** nondet stack frame created before calling main. Nondet stack dumps terminate
+** when they reach a stack frame whose redoip contains this address. Note that
+** the redoip and redofr slots of this frame may be hijacked.
+*/
+
+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.
+*/
+
+extern void MR_print_proc_id_for_debugger(
+ const MR_Stack_Layout_Entry *entry);
+extern void MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
+ const char *extra);
#endif /* MERCURY_STACK_TRACE_H */
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.9
diff -u -u -r1.9 mercury_stacks.h
--- mercury_stacks.h 1998/08/02 06:37:00 1.9
+++ mercury_stacks.h 1998/09/10 09:06:02
@@ -21,9 +21,6 @@
#define MR_stackvar(n) MR_based_stackvar(MR_sp, n)
#define detstackvar(n) MR_based_stackvar(MR_sp, n)
-#define based_detstackvar(base_sp, n) MR_based_stackvar(base_sp, n)
-#define saved_detstackvar(save_area, n) \
- MR_based_stackvar(MR_saved_sp(save_area), n)
#define incr_sp_push_msg(n, msg) \
( \
@@ -127,10 +124,6 @@
#define MR_framevar(n) MR_based_framevar(MR_curfr,n)
#define framevar(n) MR_framevar(n+1)
-#define based_framevar(base_curfr, n) \
- MR_based_framevar(base_curfr, n+1)
-#define saved_framevar(save_area, n) \
- MR_based_framevar(MR_saved_curfr(save_area), n+1)
/* DEFINITIONS FOR MANIPULATING THE NONDET STACK */
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_trace_base.c
--- mercury_trace_base.c 1998/09/29 05:11:07 1.2
+++ mercury_trace_base.c 1998/09/29 07:16:01
@@ -1,4 +1,8 @@
ADD REDO EVENTS
/*
+INIT mercury_sys_init_trace
+ENDINIT
+*/
+/*
** Copyright (C) 1997-1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
@@ -27,7 +31,7 @@
MISC RUNTIME CHANGES
** This variable is set in mercury_wrapper.c and never modified afterwards.
*/
-MR_trace_type MR_trace_handler = MR_TRACE_INTERNAL;
+MR_Trace_Type MR_trace_handler = MR_TRACE_INTERNAL;
/*
** Compiler generated tracing code will check whether MR_trace_enabled is true,
@@ -86,28 +90,57 @@
ADD TRACE DEPTH HISTOGRAMS
Bool MR_trace_from_full = 1;
-void
-MR_trace(const MR_Stack_Layout_Label *layout, MR_trace_port port,
- Word seqno, Word depth, const char * path, int max_mr_num,
- bool trace_this_event)
+int *MR_trace_histogram_all = NULL;
+int *MR_trace_histogram_exp = NULL;
+int MR_trace_histogram_max = 0;
+int MR_trace_histogram_hwm = 0;
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
MISC RUNTIME CHANGES
+
+Code *
+MR_trace(const MR_Stack_Layout_Label *layout, MR_Trace_Port port,
+ const char * path, int max_mr_num)
{
- if (MR_trace_enabled && trace_this_event) {
- (*MR_trace_func_ptr)(layout, port, seqno, depth,
- path, max_mr_num);
+ bool maybe_from_full;
+ Unsigned seqno;
+ Unsigned depth;
+
+ if (! MR_trace_enabled) {
+ return NULL;
}
+
+ maybe_from_full = layout->MR_sll_entry->MR_sle_maybe_from_full;
+ if (MR_DETISM_DET_STACK(layout->MR_sll_entry->MR_sle_detism)) {
+ if (maybe_from_full > 0 && ! MR_stackvar(maybe_from_full)) {
+ return NULL;
+ }
+
+ seqno = (Unsigned) MR_call_num_stackvar(MR_sp);
+ depth = (Unsigned) MR_call_depth_stackvar(MR_sp);
+ } else {
+ if (maybe_from_full > 0 && ! MR_framevar(maybe_from_full)) {
+ return NULL;
+ }
+
+ seqno = (Unsigned) MR_call_num_framevar(MR_curfr);
+ depth = (Unsigned) MR_call_depth_framevar(MR_curfr);
+ }
+
+ return (*MR_trace_func_ptr)(layout, port, seqno, depth,
+ path, max_mr_num);
}
-void
-MR_trace_fake(const MR_Stack_Layout_Label *layout, MR_trace_port port,
+Code *
+MR_trace_fake(const MR_Stack_Layout_Label *layout, MR_Trace_Port port,
Word seqno, Word depth, const char * path, int max_mr_num)
{
fatal_error("This executable is not set up for debugging.\n"
"Rebuild the <main>_init.c file, "
"and give the -t flag to c2init when you do so.\n"
"If you are using mmake, you can do this by including "
- "-t in C2INIT_FLAGS.\n");
- /* XXX refer to the debugging chapter in the user guide */
- /* when it is written */
+ "-t in C2INIT_FLAGS.\n"
+ "For further details, please see the Debugging chapter"
+ "of the Mercury User's Guide.\n");
+ /*NOTREACHED*/
+ return NULL;
}
void
@@ -155,6 +188,22 @@
diff -N mercury_trace.h
fprintf(fp, "Last trace event was event #%ld.\n",
(long) MR_trace_event_number);
+
+#ifdef MR_TRACE_HISTOGRAM
+ {
+ FILE *hfp;
+
+ hfp = fopen(".mercury_histogram", "w");
+ if (hfp != NULL) {
+ fprintf(fp, "All-include event histogram put"
+ " into file .mercury_histogram\n");
+ MR_trace_print_histogram(hfp, "All-inclusive",
+ MR_trace_histogram_all,
+ MR_trace_histogram_hwm);
+ fclose(hfp);
+ }
+ }
+#endif /* MR_TRACE_HISTOGRAM */
}
}
@@ -173,4 +222,49 @@
(long) MR_trace_event_number);
write(fd, buf, strlen(buf));
}
+}
+
+void
+MR_trace_print_histogram(FILE *fp, const char *which, int *histogram, int max)
+{
+ int i;
+
+ fprintf(fp, "%s histogram\n", which);
+ for (i = 1; i <= max; i++) {
+ fprintf(fp, "depth %4d: %10d", i, histogram[i]);
+ if (i + 1 <= max && histogram[i] != 0) {
+ fprintf(fp, ", branching factor %7.2f\n",
+ (float) histogram[i+1] / (float) histogram[i]);
+ } else {
+ fprintf(fp, "\n");
+ }
+ }
+}
ADD REDO EVENTS
+
+Define_extern_entry(MR_do_trace_redo_fail);
+
+BEGIN_MODULE(MR_trace_labels_module)
+ init_label(MR_do_trace_redo_fail);
+BEGIN_CODE
+
+Define_entry(MR_do_trace_redo_fail);
+#if 0
+ /* For use in case this ever needs to be debugged again. */
+ printf("MR_curfr = %p\n", MR_curfr);
+ printf("MR_redofr_slot(MR_curfr) = %p\n", MR_redofr_slot(MR_curfr));
+ printf("&MR_redo_layout_framevar(MR_redofr_slot(MR_curfr) = %p\n",
+ &MR_redo_layout_framevar(MR_redofr_slot(MR_curfr)));
+ printf("MR_redo_layout_framevar(MR_redofr_slot(MR_curfr) = %p\n",
+ MR_redo_layout_framevar(MR_redofr_slot(MR_curfr)));
+#endif
+ MR_trace((const MR_Stack_Layout_Label *)
+ MR_redo_layout_framevar(MR_redofr_slot(MR_curfr)),
+ MR_PORT_REDO, "", 0);
+ fail();
+
+END_MODULE
+
+void mercury_sys_init_trace(void); /* suppress gcc warning */
+void mercury_sys_init_trace(void) {
+ MR_trace_labels_module();
}
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_trace_base.h
--- mercury_trace_base.h 1998/09/29 05:11:08 1.2
+++ mercury_trace_base.h 1998/09/29 10:15:51
@@ -7,8 +7,9 @@
/*
** mercury_trace_base.h defines the interface between the main part
** of the runtime system (mainly mercury_wrapper.c) and the part of the
-** tracing subsystem that has to be present even if no module in the program
-** is compiled with execution tracing.
+** tracing subsystem that has to be present even if tracing is not enabled.
+** The part of the tracing system that required only when tracing is enabled
+** is in the trace directory.
*/
#ifndef MERCURY_TRACE_BASE_H
@@ -18,12 +19,13 @@
ADD REDO EVENTS
/*
** This enum should EXACTLY match the definition of the `trace_port_type' type
-** in library/debugger_interface.
+** in browser/debugger_interface.
*/
typedef enum {
MR_PORT_CALL,
MR_PORT_EXIT,
+ MR_PORT_REDO,
MR_PORT_FAIL,
MR_PORT_THEN,
MR_PORT_ELSE,
@@ -31,21 +33,28 @@
MISC RUNTIME CHANGES
MR_PORT_SWITCH,
MR_PORT_PRAGMA_FIRST,
MR_PORT_PRAGMA_LATER
-} MR_trace_port;
+} MR_Trace_Port;
+#define MR_trace_incr_seq() ((Word) ++MR_trace_call_seqno)
+#define MR_trace_incr_depth() ((Word) ++MR_trace_call_depth)
+#define MR_trace_reset_depth(d) (MR_trace_call_depth = (Unsigned) (d))
+
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
/*
** MR_trace is called from Mercury modules compiled with tracing.
-** It performs an indirect call through MR_trace_func_ptr, which
-** will point either to MR_trace_real, which is defined in the trace
-** library, or to MR_trace_fake, defined here, which just prints an
-** error message and aborts.
+** If the event is supposed to be traced, it performs an indirect call
+** through MR_trace_func_ptr, which will point either to MR_trace_real,
+** which is defined in the trace library, or to MR_trace_fake, defined here,
+** which just prints an error message and aborts.
+**
+** The return value, if not NULL, says where execution should continue
+** after the event. (NULL means it should continue as usual.)
*/
-extern void MR_trace(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int, bool);
+extern Code *MR_trace(const MR_Stack_Layout_Label *, MR_Trace_Port,
+ const char *, int);
-extern void MR_trace_fake(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int);
+extern Code *MR_trace_fake(const MR_Stack_Layout_Label *, MR_Trace_Port,
+ Unsigned, Unsigned, const char *, int);
/*
** MR_trace_init() is called from mercury_runtime_init()
@@ -72,25 +81,23 @@
MISC RUNTIME CHANGES
extern void MR_trace_end(void);
extern void MR_trace_final(void);
-#define MR_trace_incr_seq() (++MR_trace_call_seqno)
-#define MR_trace_incr_depth() (++MR_trace_call_depth)
-#define MR_trace_reset_depth(d) do { MR_trace_call_depth = (d); } while (0)
-
/*
** The globals that define the interface between the tracing subsystem
** and compiled code, and which must be initialized in the permanent part
** of the runtime.
+**
+** XXX They should probably be in MercuryEngine.
*/
-extern Word MR_trace_call_seqno;
-extern Word MR_trace_call_depth;
+extern Unsigned MR_trace_call_seqno;
+extern Unsigned MR_trace_call_depth;
typedef enum {
MR_TRACE_INTERNAL,
MR_TRACE_EXTERNAL
-} MR_trace_type;
+} MR_Trace_Type;
-extern MR_trace_type MR_trace_handler;
+extern MR_Trace_Type MR_trace_handler;
extern bool MR_trace_enabled;
extern Unsigned MR_trace_event_number;
@@ -103,5 +110,33 @@
ADD TRACE DEPTH HISTOGRAMS
extern void MR_trace_report(FILE *fp);
extern void MR_trace_report_raw(int fd);
+
+/*
+** If MR_TRACE_HISTOGRAM is defined, MR_trace maintains two arrays of integers,
+** MR_trace_histogram_all and MR_trace_histogram_exp, in which the element
+** with subscript d is incremented when a trace event occurs at depth d.
+** The intention is that the MR_trace_histogram_all records all events
+** and is never reset, which means that it records information about a whole
+** execution of the program. MR_trace_histogram_exp on the other hand can be
+** zeroed by a command from the debugger at e.g a call port, and examined at
+** e.g. an exit port, which means that it can record information about the
+** execution of a call.
+**
+** Both arrays are allocated via malloc, and resized on demand. They are
+** always the same size, and this size is stored in MR_trace_histogram_max.
+** MR_trace_histogram_hwm stores the high water mark, i.e. the biggest
+** depth number that has been encountered so far in the execution of the
+** program.
+*/
+
+#define MR_INIT_HISTOGRAM_SIZE 128
+
+extern int *MR_trace_histogram_all;
+extern int *MR_trace_histogram_exp;
+extern int MR_trace_histogram_max;
+extern int MR_trace_histogram_hwm;
+
+extern void MR_trace_print_histogram(FILE *fp, const char *which,
+ int *histogram, int max);
#endif /* MERCURY_TRACE_BASE_H */
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.26
diff -u -u -r1.26 mercury_wrapper.c
--- mercury_wrapper.c 1998/09/29 05:11:14 1.26
+++ mercury_wrapper.c 1998/09/29 06:39:24
@@ -138,8 +138,13 @@
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
/* normally ML_io_init_state (io__init_state/2)*/
void (*MR_library_finalizer)(void);
/* normally ML_io_finalize_state (io__finalize_state/2) */
-Code *MR_library_trace_browser;
- /* normally mercury__io__print_3_0 (io__print/3) */
+
+void (*MR_io_stderr_stream)(Word *);
+void (*MR_io_stdout_stream)(Word *);
+void (*MR_io_stdin_stream)(Word *);
+void (*MR_io_print_to_cur_stream)(Word, Word);
+void (*MR_io_print_to_stream)(Word, Word, Word);
+
void (*MR_DI_output_current_ptr)(Integer, Integer, Integer, Word, String,
String, Integer, Integer, Integer, Word, String, Word, Word);
/* normally ML_DI_output_current (output_current/13) */
@@ -147,9 +152,18 @@
Integer, Integer, Integer, Word, String, Word);
/* normally ML_DI_found_match (output_current/12) */
void (*MR_DI_read_request_from_socket)(Word, Word *, Integer *);
+
+/*
+** This variable has been replaced by MR_io_print_to_*_stream,
+** but the installed mkinit executable may still generate references to it.
+** We must therefore keep it until all obsolete mkinit executables have
+** been retired.
+*/
+
+Code *MR_library_trace_browser;
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
-void (*MR_trace_func_ptr)(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int);
+Code *(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *, MR_Trace_Port,
+ Unsigned, Unsigned, const char *, int);
#ifdef USE_GCC_NONLOCAL_GOTOS
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.13
diff -u -u -r1.13 mercury_wrapper.h
--- mercury_wrapper.h 1998/09/29 05:11:16 1.13
+++ mercury_wrapper.h 1998/09/29 06:39:44
@@ -42,12 +42,17 @@
FIX BUG: MAKE THE DEBUGGER PRINT TO STDOUT, NOT THE CURRENT STREAM
** The address_of_foo pointers are set to the address of
** the corresponding foo.
*/
-extern Code * program_entry_point; /* normally mercury__main_2_0; */
+extern Code *program_entry_point; /* normally mercury__main_2_0; */
extern void (*MR_library_initializer)(void);
extern void (*MR_library_finalizer)(void);
-extern Code *MR_library_trace_browser;
+extern void (*MR_io_stderr_stream)(Word *);
+extern void (*MR_io_stdout_stream)(Word *);
+extern void (*MR_io_stdin_stream)(Word *);
+extern void (*MR_io_print_to_cur_stream)(Word, Word);
+extern void (*MR_io_print_to_stream)(Word, Word, Word);
+
extern void (*address_of_mercury_init_io)(void);
extern void (*address_of_init_modules)(void);
@@ -57,44 +62,50 @@
/*
** Similarly, these are for the debugger interface; they're defined in
-** library/debugger_interface.m.
+** browser/debugger_interface.m.
*/
-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) */
+extern void (*MR_DI_output_current_vars)(Word, Word, Word);
+ /* output_current_vars/3 */
+extern void (*MR_DI_output_current_nth_var)(Word, Word);
+ /* output_current_nth_var/2 */
+extern void (*MR_DI_output_current_live_var_names)(Word, Word, Word);
+ /* output_current_live_var_names/5 */
+extern void (*MR_DI_output_current_slots)(Integer, Integer, Integer, Word,
+ String, String, Integer, Integer, Integer, String, Word);
+ /* output_current_slots/13 */
+extern bool (*MR_DI_found_match)(Integer, Integer, Integer, Word, String,
+ String, Integer, Integer, Integer, Word, String, Word);
+ /* found_match/12 */
+extern int (*MR_DI_get_var_number)(Word);
+ /* get_var_number/1 */
+extern void (*MR_DI_read_request_from_socket)(Word, Word *, Integer *);
+ /* read_request_from_socket/5 */
/*
-** ML_type_name() is defined in library/std_util.m and use in
-** runtime/mercury_trace_external.c
+** ML_type_name() is defined in library/std_util.m and used in
+** trace/mercury_trace_external.c.
*/
-String (*MR_type_name)(Word);
+extern String (*MR_type_name)(Word);
/* normally ML_type_name (type_name/1) */
+
+/*
+** This variable has been replaced by MR_io_print_to_*_stream,
+** but the installed mkinit executable may still generate references to it.
+** We must therefore keep it until all obsolete mkinit executables have
+** been retired.
+*/
+
+extern Code *MR_library_trace_browser;
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
-void (*MR_trace_func_ptr)(const MR_Stack_Layout_Label *, MR_trace_port,
- Word, Word, const char *, int);
+extern Code *(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *,
+ MR_Trace_Port, Unsigned, Unsigned, const char *, int);
extern void do_init_modules(void);
-extern const char * progname;
+extern const char *progname;
extern int mercury_argc;
-extern char ** mercury_argv;
+extern char **mercury_argv;
extern int mercury_exit_status;
/* sizes of the data areas, *including* the red zone size */
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
Index: scripts/final_grade_options.sh-subr
===================================================================
RCS file: final_grade_options.sh-subr
diff -N final_grade_options.sh-subr
--- /dev/null Wed May 28 10:49:58 1997
+++ final_grade_options.sh-subr Mon Sep 28 17:17:56 1998
@@ -0,0 +1,25 @@
+#---------------------------------------------------------------------------#
+# Copyright (C) 1998 The University of Melbourne.
+# This file may only be copied under the terms of the GNU General
+# Public License - see the file COPYING in the Mercury distribution.
+#---------------------------------------------------------------------------#
+#
+# final_grade_options.sh-subr:
+# An `sh' subroutine for handling implications between grade-related
+# options. Used by the `ml' and `mgnuc' scripts.
+#
+# The code here should be inserted after a script's option-parsing
+# loop.
+#
+#---------------------------------------------------------------------------#
+
+#
+# .debug grade implies --use-trail
+# (see comment in compiler/handle_options.m for rationale)
+#
+case $stack_trace,$require_tracing in
+ true,true)
+ use_trail=true ;;
+esac
+
+#---------------------------------------------------------------------------#
--- /mnt/munkora/home/staff/zs/mer/ws1/scripts/mdb Mon Sep 28 17:02:40 1998
+++ scripts/mdb.in Wed Sep 16 14:46:30 1998
DOCUMENT NEW DEBUG COMMAND SET
@@ -36,4 +36,6 @@
MERCURY_OPTIONS="$MERCURY_OPTIONS -Di"
export MERCURY_OPTIONS
+DEFAULT_MERCURY_DEBUGGER_INIT=@DEFAULT_MERCURY_DEBUGGER_INIT_DIR@/mdbrc
+export DEFAULT_MERCURY_DEBUGGER_INIT
exec "$@"
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mgnuc.in,v
retrieving revision 1.53
diff -u -u -r1.53 mgnuc.in
--- mgnuc.in 1998/08/07 00:50:40 1.53
+++ mgnuc.in 1998/09/28 07:19:25
FACTOR OUT SHELL CODE HANDLING GRADE IMPLICATIONS
@@ -186,14 +186,8 @@
shift
done
-#
-# .debug grade implies --use-trail
-# (see comment in compiler/handle_options.m for rationale)
-#
-case $stack_trace,$require_tracing in
- true,true)
- use_trail=true ;;
-esac
+# include the file `final_grade_options.sh-subr'
+ at FINAL_GRADE_OPTIONS@
#
# convert mgnuc options into gcc options
Index: scripts/ml.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/ml.in,v
retrieving revision 1.47
diff -u -u -r1.47 ml.in
--- ml.in 1998/09/29 05:11:33 1.47
+++ ml.in 1998/09/29 06:53:47
FACTOR OUT SHELL CODE HANDLING GRADE IMPLICATIONS
@@ -206,6 +206,9 @@
shift
done
+# include the file `final_grade_options.sh-subr'
+ at FINAL_GRADE_OPTIONS@
+
# If you haven't set mercury_libs, set it to the default value
# (shared on most systems). Note that if you have set all_libs,
# it will also have set mercury_libs.
@@ -255,15 +258,6 @@
MAYBE_STATIC_OPT=-static
;;
esac
-esac
-
-#
-# .debug grade implies --use-trail
-# (see comment in compiler/handle_options.m for rationale)
-#
-case $stack_trace,$require_tracing in
- true,true)
- use_trail=true ;;
esac
#
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.10
diff -u -u -r1.10 Mmakefile
--- Mmakefile 1998/09/29 05:11:38 1.10
+++ Mmakefile 1998/10/01 04:08:17
UPDATE TEST CASES
@@ -1,8 +1,8 @@
#-----------------------------------------------------------------------------#
-main_target: check
+main_target: check
-include ../Mmake.common
+include ../Mmake.common
RM_C=:
@@ -15,11 +15,14 @@
DEBUGGER_PROGS= \
debugger_regs \
interpreter \
-# queens
+ queens
-MCFLAGS = --trace all
+MCFLAGS = --trace deep
C2INITFLAGS = -t
+# EXTRA_CFLAGS = -g -v
+# EXTRA_MLFLAGS = -g -v
+
# Base grades `jump' and `fast' cannot be used with
# stack layouts (which are required for tracing).
@@ -60,6 +63,11 @@
SIMPLIFY THE MAINTAINANCE OF CONSISTENCY BETWEEN DEBUGGER CODE AND DOCUMENTATION
queens_lib.out: queens_lib queens_lib.inp
mdb ./queens_lib < queens_lib.inp > queens_lib.out
+mdb_command_test.out: queens mdb_command_test
+ -mdb ./queens < mdb_command_test \
+ | egrep "internal error in the trace help system" \
+ > mdb_command_test.out
+
#-----------------------------------------------------------------------------#
DEPS= $(ALLPROGS:%=$(deps_subdir)%.dep)
@@ -75,7 +83,7 @@
depend: $(DEPENDS)
-check: $(OUTS) $(RESS)
+check: $(OUTS) $(RESS) mdb_command_test.res
check_lib: $(LIBOUTS) $(LIBRESS)
Index: tests/debugger/*.{inp,exp}
<omitted>
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/bootcheck
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/bootcheck,v
retrieving revision 1.64
diff -u -u -r1.64 bootcheck
--- bootcheck 1998/09/29 05:11:44 1.64
+++ bootcheck 1998/10/01 04:11:07
@@ -885,8 +885,18 @@
DOCUMENT NEW DEBUG COMMAND SET
export PATH
fi
+ # We need to give tests/debugger access to the mdbrc and mdb_doc
+ # files in the doc directory, without hardcoding their pathnames.
+ # We must also compensate for doc/mdbrc having hardcoded within it
+ # the *installed* pathname of mdb_doc and not its current pathname.
+ cat $root/doc/mdb_doc > $root/doc/test_mdbrc
+ sed -e '/^source/d' $root/doc/mdbrc >> $root/doc/test_mdbrc
+ MERCURY_DEBUGGER_INIT=$root/doc/test_mdbrc
+ export MERCURY_DEBUGGER_INIT
+
SIMPLIFY THE MAINTAINANCE OF CONSISTENCY BETWEEN DEBUGGER CODE AND DOCUMENTATION
if test -d ../tests
then
+ cp $root/doc/mdb_command_test.inp ../tests/debugger
if test "$testdir" = ""
then
cd ../tests
@@ -899,6 +909,7 @@
cd $root
elif test -d tests
then
+ cp $root/doc/mdb_command_test.inp tests/debugger
if test "$testdir" = ""
then
cd tests
cvs diff: Diffing trace
Index: trace/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/Mmakefile,v
retrieving revision 1.1
diff -u -u -r1.1 Mmakefile
--- Mmakefile 1998/09/29 05:11:49 1.1
+++ Mmakefile 1998/09/29 07:41:54
IMPLEMENT NEW DEBUGGER COMMAND SET
@@ -25,15 +25,24 @@
# keep this list in alphabetical order, please
HDRS = \
+ mercury_macros.h \
mercury_trace.h \
+ mercury_trace_alias.h \
mercury_trace_external.h \
- mercury_trace_internal.h
+ mercury_trace_help.h \
+ mercury_trace_internal.h \
+ mercury_trace_spy.h \
+ mercury_trace_tables.h
# keep this list in alphabetical order, please
CFILES = \
mercury_trace.c \
+ mercury_trace_alias.c \
mercury_trace_external.c \
- mercury_trace_internal.c
+ mercury_trace_help.c \
+ mercury_trace_internal.c \
+ mercury_trace_spy.c \
+ mercury_trace_tables.c
OBJS = $(CFILES:.c=.o)
PIC_OBJS = $(CFILES:.c=.$(EXT_FOR_PIC_OBJECTS))
Index: trace/mercury_macros.h
===================================================================
RCS file: mercury_macros.h
diff -N mercury_macros.h
--- /dev/null Wed May 28 10:49:58 1997
+++ mercury_macros.h Tue Sep 22 12:30:04 1998
IMPLEMENT NEW DEBUGGER COMMAND SET
@@ -0,0 +1,171 @@
+/*
+** Copyright (C) 1998 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_macros.h defines macros that are useful in more than one
+** module of the Mercury runtime system.
+*/
+
+#ifndef MERCURY_MACROS_H
+#define MERCURY_MACROS_H
+
+/*
+** The MR_ensure_room_for_next macro works with a group of three variables
+** that follow the pattern
+**
+** Item widgets = NULL;
+** int widget_max = 0;
+** int widget_next = 0;
+**
+** where widgets is a pointer to a malloc'd array of items, widget_max
+** gives the number of elements in the array, and widget_next is the
+** index of the first free slot in the widgets array. Widget_max is
+** zero if and only if widgets is NULL.
+**
+** MR_ensure_room_for_next(widget, Item, INIT_SIZE) checks whether
+** there is enough room in the widgets array to add a new item.
+** If not, doubles the size of the existing widgets array, or
+** allocates an array of INIT_SIZE items if the widgets array
+** has not been initialized before.
+*/
+
+#define MR_ensure_room_for_next(base, type, init) \
+ do { \
+ if (base##_next >= base##_max) { \
+ if (base##_max == 0) { \
+ base##_max = init; \
+ base##s = checked_malloc( \
+ base##_max * sizeof(type)); \
+ } else { \
+ base##_max *= 2; \
+ base##s = checked_realloc(base##s, \
+ base##_max * sizeof(type)); \
+ } \
+ } \
+ } while(0)
+
+/*
+** MR_ensure_big_enough makes the same assumptions as MR_ensure_room_for_next,
+** and operates almost the same way. The exception is that it does not assume
+** that the array grows one item at a time; instead it ensures that the array
+** is big enough to contain the element at index `slot'. Since with this regime
+** there is no notion of the "next" slot, this macro does not access, nor does
+** it require the existence of, base##_next.
+*/
+
+#define MR_ensure_big_enough(slot, base, type, init) \
+ do { \
+ if (slot >= base##_max) { \
+ if (base##_max == 0) { \
+ base##_max = max(init, slot + 1); \
+ base##s = checked_malloc( \
+ base##_max * sizeof(type)); \
+ } else { \
+ base##_max = max(base##_max * 2, slot + 1); \
+ base##s = checked_realloc(base##s, \
+ base##_max * sizeof(type)); \
+ } \
+ } \
+ } while(0)
+
+/*
+** MR_ensure_big_enough2 works like MR_ensure_big_enough, except that
+** it resizes two arrays at once. These two arrays are named base##s1 and
+** base##s2, and since they are always the same size, they share the
+** base##_max variable.
+*/
+
+#define MR_ensure_big_enough2(slot, base, s1, s2, type, init) \
+ do { \
+ if (slot >= base##_max) { \
+ if (base##_max == 0) { \
+ base##_max = max(init, slot + 1); \
+ base##s1 = checked_malloc( \
+ base##_max * sizeof(type)); \
+ base##s2 = checked_malloc( \
+ base##_max * sizeof(type)); \
+ } else { \
+ base##_max = max(base##_max * 2, slot + 1); \
+ base##s1 = checked_realloc(base##s1, \
+ base##_max * sizeof(type)); \
+ base##s2 = checked_realloc(base##s2, \
+ base##_max * sizeof(type)); \
+ } \
+ } \
+ } while(0)
+
+/*
+** MR_bsearch(int next, int& element, bool& found, COMPARE)
+**
+** Given a sorted array, this macro performs a binary search.
+** If the search is successful, MR_bsearch sets the `found' parameter
+** to TRUE and the `element' parameter to the index of the desired item.
+** If the search is unsuccessful, MR_bsearch sets `found' to FALSE;
+** `element' will be clobbered.
+**
+** The number of the elements in the array is given by the `next' parameter.
+** The `COMPARE' parameter should be an expression which compares
+** the value at the index specified by the current value of `element'
+** with the desired value, and returns <0, 0, or >0 according to whether
+** it is less than, equal to, or greater than the desired value.
+**
+** The name of the array to be searched is not explicitly a parameter;
+** its identity is encoded in the boolean expression of the `COMPARE'
+** parameter.
+*/
+
+#define MR_bsearch(next, element, found, COMPARE) \
+ do { \
+ int lo; \
+ int hi; \
+ int diff; \
+ \
+ lo = 0; \
+ hi = (next) - 1; \
+ (found) = FALSE; \
+ while (lo <= hi) { \
+ (element) = (lo + hi) / 2; \
+ diff = (COMPARE); \
+ if (diff == 0) { \
+ (found) = TRUE; \
+ break; \
+ } else if (diff < 0) { \
+ lo = (element) + 1; \
+ } else { \
+ hi = (element) - 1; \
+ } \
+ } \
+ } while(0)
+
+/*
+** MR_prepare_insert_into_sorted(array[], int& next, int& element, COMPARE)
+**
+** Given a sorted array `items', this prepares for the insertion of a new
+** item into the array at the proper point. It find the index at which
+** the new item should be inserted, and moves all items at and above that
+** index one position to the right to make room for the new item.
+**
+** The `next' parameter holds the number of elements in the array;
+** it is incremented by this macro. The macro returns the index of the slot
+** at which the new item should be inserted in the `element' parameter.
+** The `COMPARE' parameter should be an expression which compares
+** the item at the index specified by the current value of `element' with
+** the item being inserted, and returns <0, 0, or >0 according to whether
+** it is less than, equal to, or greater than the item being inserted.
+*/
+
+#define MR_prepare_insert_into_sorted(items, next, element, COMPARE) \
+ do { \
+ (element) = (next) - 1; \
+ while ((element) >= 0 && COMPARE > 0) { \
+ items[element + 1] = items[element]; \
+ (element) -= 1; \
+ } \
+ (element) += 1; \
+ (next) += 1; \
+ } while(0)
+
+#endif /* MERCURY_MACROS_H */
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.1
diff -u -u -r1.1 mercury_trace.c
--- mercury_trace.c 1998/09/29 05:11:50 1.1
+++ mercury_trace.c 1998/09/29 07:07:55
@@ -10,8 +10,6 @@
** The trace events can be processed either by our internal debugger,
** or by an external trace-analysis style debugger. These are in
** mercury_trace_internal.c and mercury_trace_external.c respectively.
-** Utility functions usable by both the internal and external debuggers
-** are in mercury_trace_util.c.
**
** The C functions in all these modules which use any of the Mercury registers
** expect the transient registers to be in fake_reg, and the others to be in
@@ -20,113 +18,217 @@
#include "mercury_imp.h"
#include "mercury_trace.h"
-#include "mercury_trace_util.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_external.h"
+#include "mercury_trace_spy.h"
+#include "mercury_layout_util.h"
+#include "mercury_memory.h"
#include "mercury_engine.h"
#include "mercury_wrapper.h"
#include "mercury_misc.h"
+#include "mercury_macros.h"
#include <stdio.h>
#include <unistd.h> /* for the write system call */
IMPLEMENT NEW DEBUGGER COMMAND SET
-static MR_trace_cmd_info MR_trace_ctrl = { MR_CMD_GOTO, 0, 0, FALSE };
+static MR_Trace_Cmd_Info MR_trace_ctrl = { MR_CMD_GOTO, 0, 0,
+ MR_PRINT_LEVEL_SOME, FALSE };
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
-static void MR_trace_event(MR_trace_cmd_info *cmd,
+static Code *MR_trace_event(MR_Trace_Cmd_Info *cmd, bool interactive,
const MR_Stack_Layout_Label *layout,
- MR_trace_port port, Unsigned seqno, Unsigned depth,
+ MR_Trace_Port port, Unsigned seqno, Unsigned depth,
const char *path, int max_r_num);
-static void MR_trace_event_report(const MR_Stack_Layout_Label *layout,
- MR_trace_port port, Unsigned seqno, Unsigned depth,
- const char *path, int max_r_num);
ADD TRACE DEPTH HISTOGRAMS
+/*
+** Reserve room for event counts for this many depths initially.
+*/
+#define INIT_HISTOGRAM 128
+
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
/*
-** This function is called from compiled code whenever an event to be traced
+** MR_trace() is called from compiled code whenever an event to be traced
** occurs.
*/
-void
-MR_trace_real(const MR_Stack_Layout_Label *layout, MR_trace_port port,
+Code *
+MR_trace_real(const MR_Stack_Layout_Label *layout, MR_Trace_Port port,
Unsigned seqno, Unsigned depth, const char *path, int max_r_num)
{
+ MR_Spy_Action action;
+ bool match;
+
MR_trace_event_number++;
ADD TRACE DEPTH HISTOGRAMS
+#ifdef MR_TRACE_HISTOGRAM
+
+ /*
+ ** The depths do not necessarily increase one-by-one, since
+ ** a procedure from a fully traced module can be called from
+ ** deep within interface traced code.
+ */
+
+ MR_ensure_big_enough2(depth, MR_trace_histogram, _all, _exp,
+ int, INIT_HISTOGRAM);
+
+ if (depth > MR_trace_histogram_hwm) {
+ MR_trace_histogram_hwm = depth;
+ }
+
+ MR_trace_histogram_all[depth]++;
+ MR_trace_histogram_exp[depth]++;
+
+#endif /* MR_TRACE_HISTOGRAM */
+
IMPLEMENT NEW DEBUGGER COMMAND SET
switch (MR_trace_ctrl.MR_trace_cmd) {
case MR_CMD_FINISH:
- if (MR_trace_ctrl.MR_trace_stop_seqno == seqno
- && MR_port_is_final(port)) {
- MR_trace_event(&MR_trace_ctrl, layout,
- port, seqno, depth, path, max_r_num);
-
- } else if (MR_trace_ctrl.MR_trace_print_intermediate) {
- MR_trace_event_report(layout,
- port, seqno, depth, path, max_r_num);
+ if (MR_trace_ctrl.MR_trace_stop_depth == depth
+ && MR_port_is_final(port))
+ {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
}
- break;
-
case MR_CMD_GOTO:
if (MR_trace_event_number >=
- MR_trace_ctrl.MR_trace_stop_event
- || MR_event_matches_spy_point(layout)) {
- MR_trace_event(&MR_trace_ctrl, layout,
- port, seqno, depth, path, max_r_num);
- } else if (MR_trace_ctrl.MR_trace_print_intermediate) {
- MR_trace_event_report(layout,
- port, seqno, depth, path, max_r_num);
+ MR_trace_ctrl.MR_trace_stop_event)
+ {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
}
- break;
-
case MR_CMD_RESUME_FORWARD:
- if (MR_port_is_final(port)) {
- MR_trace_event(&MR_trace_ctrl, layout,
- port, seqno, depth, path, max_r_num);
- } else if (MR_trace_ctrl.MR_trace_print_intermediate) {
- MR_trace_event_report(layout,
- port, seqno, depth, path, max_r_num);
+ if (! (port == MR_PORT_REDO || port == MR_PORT_FAIL)) {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
}
- break;
+ case MR_CMD_RETURN:
+ if (port != MR_PORT_EXIT) {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
+ }
- case MR_CMD_TO_END:
- if (MR_event_matches_spy_point(layout)) {
- MR_trace_event(&MR_trace_ctrl, layout,
- port, seqno, depth, path, max_r_num);
- } else if (MR_trace_ctrl.MR_trace_print_intermediate) {
- MR_trace_event_report(layout,
- port, seqno, depth, path, max_r_num);
+ case MR_CMD_MIN_DEPTH:
+ if (MR_trace_ctrl.MR_trace_stop_depth <= depth) {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
}
- break;
+ case MR_CMD_MAX_DEPTH:
+ if (MR_trace_ctrl.MR_trace_stop_depth >= depth) {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ } else {
+ goto check_stop_print;
+ }
+
+ case MR_CMD_TO_END:
+ goto check_stop_print;
default:
- fatal_error("invalid cmd in MR_trace");
- break;
+ fatal_error("invalid command in MR_trace");
}
+
+check_stop_print:
+
+ if (MR_trace_ctrl.MR_trace_must_check) {
+ /*
+ ** The value of MR_trace_ctrl.MR_trace_must_check was
+ ** precomputed when the command was set up; it was set to TRUE
+ ** iff either MR_trace_ctrl.MR_trace_strict is FALSE (allowing
+ ** us to stop at breakpoints whose action is MR_SPY_STOP) or
+ ** MR_trace_ctrl.MR_trace_print_level is something other than
+ ** MR_PRINT_LEVEL_NONE (allowing us to print at least some
+ ** events). The precomputation avoids several jumps in the
+ ** very frequent case that MR_trace_must_check is false.
+ */
+
+ match = MR_event_matches_spy_point(layout, port, &action);
+ if (! match) {
+ if (MR_trace_ctrl.MR_trace_print_level ==
+ MR_PRINT_LEVEL_ALL)
+ {
+ return MR_trace_event(&MR_trace_ctrl, FALSE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ }
+
+ return NULL;
+ }
+
+ if ((! MR_trace_ctrl.MR_trace_strict)
+ && action == MR_SPY_STOP)
+ {
+ return MR_trace_event(&MR_trace_ctrl, TRUE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ }
+
+ if (MR_trace_ctrl.MR_trace_print_level != MR_PRINT_LEVEL_NONE) {
+ /*
+ ** It doesn't matter whether action is MR_SPY_STOP or
+ ** MR_SPY_PRINT; even if it is MR_SPY_STOP, we want
+ ** to print it if printing is allowed and we did not
+ ** stop.
+ */
+
+ return MR_trace_event(&MR_trace_ctrl, FALSE,
+ layout, port, seqno, depth,
+ path, max_r_num);
+ }
+ }
+
+ return NULL;
}
SUPPORT RETRY
USE FIXED STACK SLOTS FOR TRACE INFO
RECAST MERCURY_TRACE_UTIL AS MERCURY_LAYOUT_UTIL
-static void
-MR_trace_event(MR_trace_cmd_info *cmd,
- const MR_Stack_Layout_Label *layout, MR_trace_port port,
+static Code *
+MR_trace_event(MR_Trace_Cmd_Info *cmd, bool interactive,
+ const MR_Stack_Layout_Label *layout, MR_Trace_Port port,
Unsigned seqno, Unsigned depth, const char *path, int max_r_num)
{
int max_mr_num;
+ Code *jumpaddr;
+ Word saved_regs[MAX_FAKE_REG];
if (max_r_num + MR_NUM_SPECIAL_REG > MR_MAX_SPECIAL_REG_MR) {
max_mr_num = max_r_num + MR_NUM_SPECIAL_REG;
} else {
max_mr_num = MR_MAX_SPECIAL_REG_MR;
}
+
+ MR_copy_regs_to_saved_regs(max_mr_num, saved_regs);
- MR_copy_regs_to_saved_regs(max_mr_num);
#ifdef MR_USE_EXTERNAL_DEBUGGER
if (MR_trace_handler == MR_TRACE_EXTERNAL) {
- MR_trace_event_external(cmd, layout, port, seqno, depth, path);
+ if (!interactive) {
+ fatal_error("reporting event for external debugger");
+ }
+
+ MR_trace_event_external(cmd, layout, saved_regs,
+ port, seqno, depth, path);
+ jumpaddr = NULL;
} else {
- MR_trace_event_internal(cmd, layout, port, seqno, depth, path);
+ jumpaddr = MR_trace_event_internal(cmd, interactive,
+ layout, saved_regs, port, seqno,
+ depth, path, &max_mr_num);
}
#else
/*
@@ -134,28 +236,20 @@
** This is enforced by mercury_wrapper.c.
*/
- MR_trace_event_internal(cmd, layout, port, seqno, depth, path);
+ jumpaddr = MR_trace_event_internal(cmd, interactive,
+ layout, saved_regs, port, seqno,
+ depth, path, &max_mr_num);
#endif
- MR_copy_saved_regs_to_regs(max_mr_num);
-}
-static void
-MR_trace_event_report(const MR_Stack_Layout_Label *layout, MR_trace_port port,
- Unsigned seqno, Unsigned depth, const char *path, int max_r_num)
-{
-#ifdef MR_USE_EXTERNAL_DEBUGGER
- if (MR_trace_handler == MR_TRACE_EXTERNAL) {
- fatal_error("trying to report an event to external debugger");
- } else {
- MR_trace_event_internal_report(layout,
- port, seqno, depth, path);
- }
-#else
/*
- ** We should get here only if MR_trace_handler == MR_TRACE_INTERNAL.
- ** This is enforced by mercury_wrapper.c.
+ ** Whenever the debugger changes the flow of control, e.g. by
+ ** executing a retry command, it also sets up the saved registers
+ ** to the state that is appropriate for the label at which execution
+ ** will resume. There may be more registers live at that point than
+ ** at the point at which MR_trace was called. Therefore max_mr_num
+ ** should also be set appropriately when executing a retry command.
*/
- MR_trace_event_internal_report(layout, port, seqno, depth, path);
-#endif
+ MR_copy_saved_regs_to_regs(max_mr_num, saved_regs);
+ return jumpaddr;
}
Index: trace/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.h,v
retrieving revision 1.1
diff -u -u -r1.1 mercury_trace.h
--- mercury_trace.h 1998/09/29 05:11:51 1.1
+++ mercury_trace.h 1998/09/29 06:58:57
@@ -5,46 +5,22 @@
IMPLEMENT NEW DEBUGGER COMMAND SET
*/
/*
-** mercury_trace.h has two functions.
+** mercury_trace.h defines the interface by which the internal and external
+** debuggers can control how the tracing subsystem treats events.
**
-** (a) It defines the interface between the tracing subsystem of the runtime
-** and compiled code.
-**
-** (b) It defines the interface by which the internal and external debuggers
-** can control how the tracing subsystem treats events.
-**
** The macros, functions and variables of this module are intended to be
** referred to only from code generated by the Mercury compiler, and from
** hand-written code in the Mercury runtime or the Mercury standard library,
** and even then only if at least some part of the program was compiled
** with some form of execution tracing.
**
-** The parts of the tracing system that need to be present even when no
-** part of the program is compiled with execution tracing are in the module
-** mercury_trace_base.
+** The parts of the tracing system that need to be present even when tracing
+** is not enabled are in the module runtime/mercury_trace_base.
*/
#ifndef MERCURY_TRACE_H
#define MERCURY_TRACE_H
-#include "mercury_trace_base.h"
-
-/* The interface between the tracing subsystem and compiled code. */
-
-#define MR_trace_incr_seq() (++MR_trace_call_seqno)
-#define MR_trace_incr_depth() (++MR_trace_call_depth)
-#define MR_trace_reset_depth(d) do { MR_trace_call_depth = (d); } while (0)
-
-extern void MR_trace_real(
- const MR_Stack_Layout_Label *, /* layout info for the event */
- MR_trace_port,
- Word, /* call sequence number */
- Word, /* call depth */
- const char *, /* path to event goal within procedure */
- int); /* highest numbered rN register in use */
-
-/* The interface between the debuggers and the tracing subsystem. */
-
/*
** MR_trace_cmd says what mode the tracer is in, i.e. how events should be
** treated.
@@ -54,11 +30,20 @@
**
** If MR_trace_cmd == MR_CMD_FINISH, the event handler will stop at the next
** event that specifies the procedure invocation whose call number is in
-** MR_trace_stop_seqno and whose port is final.
+** MR_trace_stop_seqno and whose port is EXIT or FAIL.
**
** If MR_trace_cmd == MR_CMD_RESUME_FORWARD, the event handler will stop at
-** the next event of any call whose port is *not* final.
+** the next event of any call whose port is *not* REDO or FAIL.
+**
+** If MR_trace_cmd == MR_CMD_RETURN, the event handler will stop at
+** the next event of any call whose port is *not* EXIT.
**
+** If MR_trace_cmd == MR_CMD_MIN_DEPTH, the event handler will stop at
+** the next event of any call whose depth is at least MR_trace_stop_depth.
+**
+** If MR_trace_cmd == MR_CMD_MAX_DEPTH, the event handler will stop at
+** the next event of any call whose depth is at most MR_trace_stop_depth.
+**
** If MR_trace_cmd == MR_CMD_TO_END, the event handler will not stop
** until the end of the program.
**
@@ -66,20 +51,42 @@
** summary line for the event if MR_trace_print_intermediate is true.
*/
+typedef enum {
+ MR_CMD_GOTO,
+ MR_CMD_FINISH,
+ MR_CMD_RESUME_FORWARD,
+ MR_CMD_RETURN,
+ MR_CMD_MIN_DEPTH,
+ MR_CMD_MAX_DEPTH,
+ MR_CMD_TO_END
+} MR_Trace_Cmd_Type;
+
typedef enum {
- MR_CMD_GOTO, /* stop at an event with a given number */
- MR_CMD_FINISH, /* stop when exiting/failing out of a proc */
- MR_CMD_RESUME_FORWARD, /* stop at the next non-final port */
- MR_CMD_TO_END /* do not stop until the end of execution */
-} MR_trace_cmd_type;
+ MR_PRINT_LEVEL_NONE, /* no events at all */
+ MR_PRINT_LEVEL_SOME, /* events matching an active spy point */
+ MR_PRINT_LEVEL_ALL /* all events */
+} MR_Trace_Print_Level;
typedef struct {
- MR_trace_cmd_type MR_trace_cmd;
- Unsigned MR_trace_stop_seqno;
- Unsigned MR_trace_stop_event;
- bool MR_trace_print_intermediate;
-} MR_trace_cmd_info;
+ MR_Trace_Cmd_Type MR_trace_cmd;
+ Unsigned MR_trace_stop_depth; /* if MR_CMD_FINISH */
+ Unsigned MR_trace_stop_event; /* if MR_CMD_GOTO */
+ MR_Trace_Print_Level MR_trace_print_level;
+ bool MR_trace_strict;
+
+ /*
+ ** The next field is an optimization;
+ ** it must be set to !MR_trace_strict ||
+ ** MR_trace_print_level != MR_PRINT_LEVEL_NONE
+ */
+ bool MR_trace_must_check;
+} MR_Trace_Cmd_Info;
+
+#define MR_port_is_final(port) ((port) == MR_PORT_EXIT || \
+ (port) == MR_PORT_FAIL)
+
+#define MR_port_is_interface(port) ((port) < MR_PORT_FAIL)
-#define MR_port_is_final(port) (port == MR_PORT_EXIT || port == MR_PORT_FAIL)
+#define MR_port_is_entry(port) ((port) == MR_PORT_CALL)
#endif /* MERCURY_TRACE_H */
Index: trace/mercury_trace_alias.c
===================================================================
RCS file: mercury_trace_alias.c
diff -N mercury_trace_alias.c
--- /dev/null Wed May 28 10:49:58 1997
+++ mercury_trace_alias.c Mon Sep 21 20:03:43 1998
IMPLEMENT NEW DEBUGGER COMMAND SET
@@ -0,0 +1,148 @@
+/*
+** Copyright (C) 1998 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_trace_alias.h
+**
+** Author: zs.
+*/
+
+#include "mercury_imp.h"
+#include "mercury_trace_alias.h"
+#include "mercury_macros.h"
+
+static MR_Alias *MR_alias_records = NULL;
+static int MR_alias_record_max = 0;
+static int MR_alias_record_next = 0;
+
+/* The initial size of the alias table. */
+#define INIT_ALIAS_COUNT 32
+
+static void MR_trace_print_alias_num(FILE *fp, int slot);
+
+void
+MR_trace_add_alias(char *name, char **words, int word_count)
+{
+ bool found;
+ int slot;
+ int i;
+ int count;
+
+ MR_bsearch(MR_alias_record_next, slot, found,
+ strcmp(MR_alias_records[slot].MR_alias_name, name));
+ if (found) {
+ count = MR_alias_records[slot].MR_alias_word_count;
+ for (i = 0; i < count; i++) {
+ free(MR_alias_records[slot].MR_alias_words[i]);
+ }
+
+ free(MR_alias_records[slot].MR_alias_name);
+ free(MR_alias_records[slot].MR_alias_words);
+ } else {
+ MR_ensure_room_for_next(MR_alias_record, MR_Alias,
+ INIT_ALIAS_COUNT);
+ MR_prepare_insert_into_sorted(MR_alias_records,
+ MR_alias_record_next, slot,
+ strcmp(MR_alias_records[slot].MR_alias_name,
+ name));
+ }
+
+ MR_alias_records[slot].MR_alias_name = MR_copy_string(name);
+ MR_alias_records[slot].MR_alias_word_count = word_count;
+ MR_alias_records[slot].MR_alias_words = checked_malloc(word_count
+ * sizeof(char *));
+ for (i = 0; i < word_count; i++) {
+ MR_alias_records[slot].MR_alias_words[i]
+ = MR_copy_string(words[i]);
+ }
+}
+
+bool
+MR_trace_remove_alias(const char *name)
+{
+ bool found;
+ int slot;
+ int i;
+ int count;
+
+ MR_bsearch(MR_alias_record_next, slot, found,
+ strcmp(MR_alias_records[slot].MR_alias_name, name));
+ if (! found) {
+ return FALSE;
+ } else {
+ count = MR_alias_records[slot].MR_alias_word_count;
+ for (i = 0; i < count; i++) {
+ free(MR_alias_records[slot].MR_alias_words[i]);
+ }
+
+ free(MR_alias_records[slot].MR_alias_name);
+ free(MR_alias_records[slot].MR_alias_words);
+
+ for (i = slot; i < MR_alias_record_next - 1; i++) {
+ MR_alias_records[slot] = MR_alias_records[slot+1];
+ }
+
+ MR_alias_record_next--;
+
+ return TRUE;
+ }
+}
+
+bool
+MR_trace_lookup_alias(const char *name,
+ char ***words_ptr, int *word_count_ptr)
+{
+ bool found;
+ int slot;
+
+ MR_bsearch(MR_alias_record_next, slot, found,
+ strcmp(MR_alias_records[slot].MR_alias_name, name));
+ if (found) {
+ *word_count_ptr = MR_alias_records[slot].MR_alias_word_count;
+ *words_ptr = MR_alias_records[slot].MR_alias_words;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+void
+MR_trace_print_alias(FILE *fp, const char *name)
+{
+ bool found;
+ int slot;
+
+ MR_bsearch(MR_alias_record_next, slot, found,
+ strcmp(MR_alias_records[slot].MR_alias_name, name));
+ if (found) {
+ MR_trace_print_alias_num(fp, slot);
+ } else {
+ fprintf(fp, "There is no such alias.\n");
+ }
+}
+
+void
+MR_trace_print_all_aliases(FILE *fp)
+{
+ int slot;
+
+ for (slot = 0; slot < MR_alias_record_next; slot++) {
+ MR_trace_print_alias_num(fp, slot);
+ }
+}
+
+static void
+MR_trace_print_alias_num(FILE *fp, int slot)
+{
+ int i;
+
+ fprintf(fp, "%-6s => ", MR_alias_records[slot].MR_alias_name);
+ for (i = 0; i < MR_alias_records[slot].MR_alias_word_count; i++) {
+ fprintf(fp, " %s", MR_alias_records[slot].MR_alias_words[i]);
+ }
+
+ fprintf(fp, "\n");
+}
Index: trace/mercury_trace_alias.h
===================================================================
RCS file: mercury_trace_alias.h
diff -N mercury_trace_alias.h
--- /dev/null Wed May 28 10:49:58 1997
+++ mercury_trace_alias.h Tue Sep 22 12:30:04 1998
IMPLEMENT NEW DEBUGGER COMMAND SET
@@ -0,0 +1,67 @@
+/*
+** Copyright (C) 1998 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_trace_alias.h
+**
+** Defines the interface of the alias system for the internal debugger.
+*/
+
+#ifndef MERCURY_TRACE_ALIAS_H
+#define MERCURY_TRACE_ALIAS_H
+
+#include <stdio.h>
+
+typedef struct {
+ char *MR_alias_name;
+ char **MR_alias_words;
+ int MR_alias_word_count;
+} MR_Alias;
+
+/*
+** Add an alias with the given name and expansion to the list.
+** The name, the words in the expansion and the array of pointers to the
+** expansion will all be copied, so their storage can be released
+** when MR_trace_add_alias returns.
+**
+** Overwrites any previous alias with the same name.
+*/
+
+extern void MR_trace_add_alias(char *name, char **words,
+ int word_count);
+
+/*
+** Remove the given alias from the list. Returns FALSE if there is no
+** such alias, and TRUE if there was such an alias and the removal was
+** successful.
+*/
+
+extern bool MR_trace_remove_alias(const char *name);
+
+/*
+** Looks up whether the given alias exists. If yes, returns TRUE, and
+** sets *words_ptr to point to a vector of words forming the alias expansion,
+** and *word_count_ptr to the number of words in the expansion. If no,
+** returns FALSE.
+*/
+
+extern bool MR_trace_lookup_alias(const char *name,
+ char ***words_ptr, int *word_count_ptr);
+
+/*
+** Print the alias of the given name, if it exists, and an error message
+** if it does not.
+*/
+
+extern void MR_trace_print_alias(FILE *fp, const char *name);
+
+/*
+** Print all the aliases to the given file.
+*/
+
+extern void MR_trace_print_all_aliases(FILE *fp);
+
+#endif /* MERCURY_TRACE_ALIAS_H */
More information about the developers
mailing list