for review: Stack dumps -- the main course (round 2)
Tyson Dowd
trd at cs.mu.OZ.AU
Fri Mar 6 16:56:07 AEDT 1998
Hi,
Here's an update of my diff. There are quite a few changes, and
a major merge, so I've re-posted the whole thing.
---
This adds stack traces (well, at the moment, just a "stack dump") to
the library and runtime system.
You need to compile with MCFLAGS = --stack-trace and
MGNUCFLAGS = --stack-trace (or EXTRA_MCFLAGS and EXTRA_MGNUCFLAGS)
to obtain an executable capable of displaying a stack dump. This isn't
intended to be the final mechanism -- probably a new grade or debugging
grade would be the best solution.
Presently, any call to error/1 attempts to do a stack dump.
The results look like this:
Software error: map__det_insert: key already present
Stack dump follows (determinisitic stack only):
mercury__map__det_insert_from_corresponding_lists_4_0
mercury__map_error__create_map_error_2_0
mercury__map_error__do_call_this_2_0
mercury__main_2_0
===================================================================
Estimated hours taken: 12
Add support for stack dumps, do a stack dump from error/1.
compiler/Mmakefile:
library/Mmakefile:
profiler/Mmakefile:
runtime/Mmakefile:
Insert EXTRA_MGNUCFLAGS before CFLAGS or EXTRA_CFLAGS
becasue mgnuc stops processing its options when it
encounters a non-mgnuc option.
library/require.m:
Call MR_dump_stack if error is called.
runtime/Mmakefile:
runtime/mercury_imp.h:
Add #includes of new files.
runtime/mercury_type_info.h:
Remove conditional definition of MR_STATIC_CODE_ADDRESSES
(moved into mercury_conf.h.in).
runtime/mercury_accurate_gc.h:
Remove stack_layout stuff, leave this file for accurate
GC specific definitions.
runtime/mercury_conf.h.in:
Add conditional definitions of MR_INSERT_LABELS,
MR_USE_STACK_LAYOUTS, MR_NEED_INITIALIZATION_CODE and
MR_STATIC_CODE_ADDRESSES, depending on various other options.
runtime/mercury_goto.h:
Insert labels into label table if MR_INSERT_LABELS is defined,
rather than NATIVE_GC.
util/mkinit.c:
Initialize if MR_NEED_INITIALIZATION_CODE is defined, rather than
NATIVE_GC.
runtime/mercury_stack_layout.h:
All the old stack layout definitions from mercury_accurate_gc.h.
Add code for MR_DETERMINSIM_IS_DET_CODE_MODEL.
runtime/mercury_stack_trace.c:
runtime/mercury_stack_trace.h:
Implement MR_dump_stack which just provides a dump of the stack
as far as possible.
Set MR_INSERT_LABELS and MR_USE_STACK_LAYOUTS if MR_STACK_TRACE
is set.
runtime/mercury_grade.h:
Add _strce if stack tracing is enabled in the grade. This
might not be a permanent change.
runtime/mercury_ho_call.c:
Remove unused label declarations.
scripts/mgnuc.in:
Add --stack-trace and --no-stack-trace options.
Consolidate some duplicate code.
Index: compiler/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/Mmakefile,v
retrieving revision 1.8
diff -u -r1.8 Mmakefile
--- Mmakefile 1998/02/18 23:41:50 1.8
+++ Mmakefile 1998/03/05 07:06:28
@@ -32,7 +32,7 @@
MERCURY_INT_DIR=$(LIBRARY_DIR) \
$(MC) --cflags -I$(BOEHM_GC_DIR) --split-c-files -c
MGNUC = MERCURY_C_INCL_DIR=$(RUNTIME_DIR) $(SCRIPTS_DIR)/mgnuc
-MGNUCFLAGS = -I$(BOEHM_GC_DIR) $(EXTRA_CFLAGS)
+MGNUCFLAGS = $(EXTRA_MGNUCFLAGS) -I$(BOEHM_GC_DIR) $(EXTRA_CFLAGS)
C2INIT = \
MERCURY_MOD_LIB_MODS="$(RUNTIME_DIR)/runtime.init $(LIBRARY_DIR)/libmercury.init" \
MERCURY_MKINIT=$(UTIL_DIR)/mkinit $(SCRIPTS_DIR)/c2init
Index: library/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/Mmakefile,v
retrieving revision 1.23
diff -u -r1.23 Mmakefile
--- Mmakefile 1998/03/04 05:10:14 1.23
+++ Mmakefile 1998/03/05 07:05:36
@@ -80,7 +80,7 @@
--cflags "-I$(RUNTIME_DIR) -I$(BOEHM_GC_DIR) $(EXTRA_CFLAGS)" \
$(INTERMODULE_OPTS) $(CHECK_TERM_OPTS)
MGNUC = MERCURY_C_INCL_DIR=$(RUNTIME_DIR) $(SCRIPTS_DIR)/mgnuc
-MGNUCFLAGS = -I$(RUNTIME_DIR) -I$(BOEHM_GC_DIR) \
+MGNUCFLAGS = $(EXTRA_MGNUCFLAGS) -I$(RUNTIME_DIR) -I$(BOEHM_GC_DIR) \
$(DLL_CFLAGS) $(EXTRA_CFLAGS)
LDFLAGS = -L$(BOEHM_GC_DIR) -L$(RUNTIME_DIR)
LDLIBS = -lmer \
Index: library/require.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/require.m,v
retrieving revision 1.17
diff -u -r1.17 require.m
--- require.m 1998/01/23 12:33:31 1.17
+++ require.m 1998/03/03 07:58:21
@@ -47,7 +47,10 @@
/* error/1, from require.m */
-:- pragma c_header_code("#include <stdio.h>").
+:- pragma c_header_code("
+#include <stdio.h>
+#include ""mercury_stack_trace.h""
+").
% Hopefully error/1 won't be called often (!), so no point inlining it.
:- pragma no_inline(error/1).
@@ -55,6 +58,7 @@
:- pragma c_code(error(Message::in), "
fflush(stdout);
fprintf(stderr, ""Software error: %s\\n"", Message);
+ MR_dump_stack(MR_succip, MR_sp);
exit(1);
#ifndef USE_GCC_NONLOCAL_GOTOS
return 0; /* suppress some dumb warnings */
Index: profiler/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/profiler/Mmakefile,v
retrieving revision 1.5
diff -u -r1.5 Mmakefile
--- Mmakefile 1997/11/06 06:19:29 1.5
+++ Mmakefile 1998/03/05 07:07:05
@@ -26,7 +26,7 @@
MCS = MERCURY_C_INCL_DIR=$(RUNTIME_DIR) \
MERCURY_INT_DIR=$(LIBRARY_DIR) $(MC) --split-c-files -c
MGNUC = MERCURY_C_INCL_DIR=$(RUNTIME_DIR) $(SCRIPTS_DIR)/mgnuc
-MGNUCFLAGS = -I$(BOEHM_GC_DIR) $(EXTRA_CFLAGS)
+MGNUCFLAGS = $(EXTRA_MGNUCFLAGS) -I$(BOEHM_GC_DIR) $(EXTRA_CFLAGS)
C2INIT = \
MERCURY_MOD_LIB_MODS="$(RUNTIME_DIR)/runtime.init $(LIBRARY_DIR)/libmercury.init" \
MERCURY_MKINIT=$(UTIL_DIR)/mkinit $(SCRIPTS_DIR)/c2init
Index: runtime/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/Mmakefile,v
retrieving revision 1.21
diff -u -r1.21 Mmakefile
--- Mmakefile 1997/12/05 15:56:25 1.21
+++ Mmakefile 1998/03/05 06:48:35
@@ -16,7 +16,7 @@
CFLAGS = -I$(MERCURY_DIR)/runtime -I$(MERCURY_DIR)/boehm_gc -g \
$(DLL_CFLAGS) $(EXTRA_CFLAGS)
MGNUC = MERCURY_C_INCL_DIR=. $(SCRIPTS_DIR)/mgnuc
-MGNUCFLAGS = --no-ansi $(CFLAGS)
+MGNUCFLAGS = --no-ansi $(EXTRA_MGNUCFLAGS) $(CFLAGS)
MOD2C = $(SCRIPTS_DIR)/mod2c
#-----------------------------------------------------------------------------#
@@ -41,6 +41,7 @@
mercury_imp.h \
mercury_init.h \
mercury_label.h \
+ mercury_stack_layout.h \
mercury_memory.h \
mercury_misc.h \
mercury_overflow.h \
@@ -51,6 +52,7 @@
mercury_spinlock.h \
mercury_std.h \
mercury_stacks.h \
+ mercury_stack_trace.h \
mercury_string.h \
mercury_table.h \
mercury_tags.h \
@@ -93,6 +95,7 @@
mercury_prof_mem.c \
mercury_regs.c \
mercury_spinlock.c \
+ mercury_stack_trace.c \
mercury_table.c \
mercury_timing.c \
mercury_trace.c \
Index: runtime/mercury_accurate_gc.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_accurate_gc.h,v
retrieving revision 1.6
diff -u -r1.6 mercury_accurate_gc.h
--- mercury_accurate_gc.h 1998/02/03 08:17:17 1.6
+++ mercury_accurate_gc.h 1998/03/05 02:40:35
@@ -15,289 +15,5 @@
/*---------------------------------------------------------------------------*/
-/*
-** Defintions used for accessing and creating stack_layouts.
-**
-** 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, you may need to change compiler/stack_layout.m
-** as well.
-*/
-
-#ifdef NATIVE_GC
- #define MR_USE_STACK_LAYOUTS
-#endif
-
-/*
-** Definitions for MR_PredFunc
-*/
-
-typedef enum { MR_PREDICATE, MR_FUNCTION } MR_PredFunc;
-
-/*
-** Definitions for MR_Determinism
-**
-** The max_soln component of the determinism is encoded in the 1 and 2 bits.
-** The can_fail component of the determinism is encoded in the 4 bit.
-** The first_solution component of the determinism is encoded in the 8 bit.
-**
-** MR_DETISM_AT_MOST_MANY could also be defined as ((d) & 3) == 3),
-** but this would be less efficient, since the C compiler does not know
-** that we do not set the 1 bit unless we also set the 2 bit.
-*/
-
-typedef Word MR_Determinism;
-
-#define MR_DETISM_DET 6
-#define MR_DETISM_SEMI 2
-#define MR_DETISM_NON 3
-#define MR_DETISM_MULTI 7
-#define MR_DETISM_ERRONEOUS 4
-#define MR_DETISM_FAILURE 0
-#define MR_DETISM_CCNON 10
-#define MR_DETISM_CCMULTI 14
-
-#define MR_DETISM_AT_MOST_ZERO(d) ((d) & 3) == 0)
-#define MR_DETISM_AT_MOST_ONE(d) ((d) & 3) == 2)
-#define MR_DETISM_AT_MOST_MANY(d) ((d) & 1) != 0)
-
-#define MR_DETISM_CAN_FAIL(d) ((d) & 4) != 0)
-
-#define MR_DETISM_FIRST_SOLN(d) ((d) & 8) != 0)
-
-/*
-** Definitions for "MR_Live_Lval"
-**
-** MR_Live_Lval is a Word which describes an lval. This includes:
-** - 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
-** data field describing which stack slot number or register number.
-**
-** Lval Tag Rest
-** r(Num) 0 Num
-** f(Num) 1 Num
-** stackvar(Num) 2 Num
-** framevar(Num) 3 Num
-** succip 4
-** maxfr 5
-** curfr 6
-** hp 7
-** sp 8
-** unknown 9 (The location is not known)
-**
-** The type MR_Lval_Type describes the different tag values.
-**
-** This data is generated in compiler/stack_layout.m, which must be kept
-** in sync with the constants defined here.
-*/
-
-typedef Word MR_Live_Lval;
-
-typedef enum {
- MR_LVAL_TYPE_R,
- MR_LVAL_TYPE_F,
- MR_LVAL_TYPE_STACKVAR,
- MR_LVAL_TYPE_FRAMEVAR,
- MR_LVAL_TYPE_SUCCIP,
- MR_LVAL_TYPE_MAXFR,
- MR_LVAL_TYPE_CURFR,
- MR_LVAL_TYPE_HP,
- MR_LVAL_TYPE_SP,
- MR_LVAL_TYPE_UNKNOWN
-} MR_Lval_Type;
-
-#define MR_LIVE_LVAL_TAGBITS 8
-
-#define MR_LIVE_LVAL_TYPE(Lval) \
- ((MR_Lval_Type) ((Lval) & ((1 << MR_LIVE_LVAL_TAGBITS) - 1)))
-
-#define MR_LIVE_LVAL_NUMBER(Lval) \
- ((Word) (Lval) >> MR_LIVE_LVAL_TAGBITS)
-
-/*
-** Definitions for MR_Live_Type
-**
-** MR_Live_Type describes live data. This includes:
-** - succip, hp, curfr, maxfr, redoip, and
-** mercury data values (vars).
-**
-** 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,
-** containing a type_info and an instantiation represention.
-**
-** This data is generated in compiler/stack_layout.m, which must be kept
-** in sync with the constants defined here.
-*/
-
-typedef Word MR_Live_Type;
-
-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_Lval_NonVar;
-
-typedef struct {
- Word type;
- Word inst;
-} MR_Var_Shape_Info;
-
-#define MR_LIVE_TYPE_IS_VAR(T) ( (Word) T > TYPELAYOUT_MAX_VARINT )
-
-#define MR_LIVE_TYPE_GET_NONVAR(T) \
- ((MR_Lval_NonVar) T)
-
-#define MR_LIVE_TYPE_GET_VAR_TYPE(T) \
- ((Word) ((MR_Var_Shape_Info *) T)->type)
-
-#define MR_LIVE_TYPE_GET_VAR_INST(T) \
- ((Word) ((MR_Var_Shape_Info *) T)->inst)
-
-/*
-** Macros to support hand-written C code.
-*/
-
-/*
-** Define a stack layout for a label that you know very little about.
-** It's just a generic entry label, no useful information, except
-** the code address for the label.
-*/
-#ifdef MR_USE_STACK_LAYOUTS
- #define MR_MAKE_STACK_LAYOUT_ENTRY(l) \
- const struct mercury_data__stack_layout__##l##_struct { \
- Code * f1; \
- Integer f2; \
- Integer f3; \
- Integer f4; \
- } mercury_data__stack_layout__##l = { \
- STATIC(l), \
- (Integer) -1, /* Unknown determinism */ \
- (Integer) -1, /* Unknown number of stack slots */ \
- (Integer) MR_LVAL_TYPE_UNKNOWN /* Unknown succip location */ \
- };
-#else
- #define MR_MAKE_STACK_LAYOUT_ENTRY(l)
-#endif /* MR_USE_STACK_LAYOUTS */
-
-/*
-** Define a stack layout for an internal label. Need to supply the
-** label name (l) and the entry label name (e).
-**
-** The only useful information in this structure is the code address
-** and the reference to the entry for this label.
-*/
-#ifdef MR_USE_STACK_LAYOUTS
- #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e) \
- const struct mercury_data__stack_layout__##l##_struct { \
- const Word * f1; \
- Integer f2; \
- const Word * f3; \
- } mercury_data__stack_layout__##l = { \
- (const Word *) &mercury_data__stack_layout__##e, \
- (Integer) -1, /* Unknown number of live values */ \
- (const Word *) NULL /* No list of live valeus */ \
- };
-#else
- #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)
-#endif /* MR_USE_STACK_LAYOUTS */
-
-/*
-** Define a stack layout for an internal label.
-** Need to supply the label name (l) and the number (x), eg for
-** label_name_i3, x is 3. It is assumed the entry label for that
-** corresponds to this label is the label name without the _iX suffix.
-**
-** (MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY, above, is a little
-** more general than MR_MAKE_STACK_LAYOUT_INTERNAL. This macro can
-** only describe relationships between labels that have the same
-** base -- MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY can create layouts
-** for internal labels no matter what the name of the entry layout is).
-**
-** The only useful information in this structure is the code address
-** and the reference to the entry for this label.
-*/
-#ifdef MR_USE_STACK_LAYOUTS
- #define MR_MAKE_STACK_LAYOUT_INTERNAL(e, x) \
- const struct mercury_data__stack_layout__##e##_i##x##_struct { \
- const Word * f1; \
- Integer f2; \
- const Word * f3; \
- } mercury_data__stack_layout__##e##_i##x = { \
- (const Word *) &mercury_data__stack_layout__##e, \
- (Integer) -1, /* Unknown number of live values */ \
- (const Word *) NULL /* No list of live valeus */ \
- };
-#else
- #define MR_MAKE_STACK_LAYOUT_INTERNAL(l, x)
-#endif /* MR_USE_STACK_LAYOUTS */
-
-/*
-** Structs and macros to support stack layouts.
-*/
-
-typedef struct MR_stack_layout_shape_struct {
- Word *MR_sls_type;
- Word MR_sls_inst;
-} MR_stack_layout_shape;
-
-typedef struct MR_stack_layout_var_struct {
- Integer MR_slv_locn;
- MR_stack_layout_shape *MR_slv_shape;
-} MR_stack_layout_var;
-
-typedef struct MR_stack_layout_vars_struct {
- MR_stack_layout_var *MR_slvs_pairs;
- String *MR_slvs_names;
- Word *MR_slvs_tvars;
-} MR_stack_layout_vars;
-
-typedef struct MR_stack_layout_entry_struct {
- Code *MR_sle_code_addr;
- MR_Determinism MR_sle_detism;
- Integer MR_sle_stack_slots;
- MR_Live_Lval MR_sle_succip_locn;
- /* the fields from here onwards are present only with procid layouts */
- MR_PredFunc MR_sle_pred_or_func;
- String MR_sle_decl_module;
- String MR_sle_def_module;
- String MR_sle_name;
- Integer MR_sle_arity;
- Integer MR_sle_mode;
- /* the fields from here onwards are present only with trace layouts */
- Integer MR_sle_in_arg_count;
- MR_stack_layout_vars MR_sle_in_arg_info;
- Integer MR_sle_out_arg_count;
- MR_stack_layout_vars MR_sle_out_arg_info;
-} MR_stack_layout_entry;
-
-typedef struct MR_stack_layout_label_struct {
- MR_stack_layout_entry *MR_sll_entry;
- Integer MR_sll_var_count;
- /* the last field is present only if MR_sll_var_count > 0 */
- MR_stack_layout_vars MR_sll_var_info;
-} MR_stack_layout_label;
-
-/* The following macros support obsolete code. */
-#define MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(s) \
- ((Code *) field(0, (s), 0))
-
-#define MR_CONT_STACK_LAYOUT_GET_ENTRY_LAYOUT(s) \
- (field(0, (s), 0))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_NUM_SLOTS(s) \
- (field(0, (s), 2))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_CODE_MODEL(s) \
- (field(0, (s), 1) & 1)
-
-#define MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(s) \
- (field(0, (s), 3))
-
/*---------------------------------------------------------------------------*/
#endif /* not MERCURY_ACCURATE_GC_H */
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.3
diff -u -r1.3 mercury_conf.h.in
--- mercury_conf.h.in 1997/11/23 09:31:48 1.3
+++ mercury_conf.h.in 1998/03/05 06:28:29
@@ -7,7 +7,8 @@
/*
** mercury_conf.h.in -
** Various configuration parameters, determined automatically by
-** the auto-configuration script.
+** the auto-configuration script. Implications of configuration
+** parameters, and combinations of paramters.
*/
/*
@@ -197,5 +198,50 @@
** (True for SunOS 4.x.)
*/
#undef MR_CANNOT_GROK_ASM_TYPE_DIRECTIVE
+
+/*
+** Implications of configuration parameters.
+**
+** Meaning of parameters:
+**
+** MR_USE_STACK_LAYOUTS -- stack layouts are in use, generate stack
+** layout structures.
+** MR_INSERT_LABELS -- labels need to be inserted into the label table.
+** (this also means the initialization code needs
+** to be run).
+** MR_NEED_INITIALIZATION_CODE -- the module specific initialization code
+** is needed (doesn't actually run the code,
+** however).
+*/
+
+#if defined(MR_STACK_TRACE) || defined(NATIVE_GC)
+ #define MR_USE_STACK_LAYOUTS
+ #define MR_INSERT_LABELS
+#endif
+
+#if defined(SPEED) && !defined(DEBUG_GOTOS)
+ #define MR_INSERT_LABELS
+#endif
+
+/*
+** Static code addresses are available unless using gcc non-local gotos,
+** without assembler labels.
+*/
+#if (defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS))
+ #undef MR_STATIC_CODE_ADDRESSES
+#else
+ #define MR_STATIC_CODE_ADDRESSES
+#endif
+
+/*
+** You need to run initialization code for grades without static
+** code addresses, for profiling, and any time you need to insert
+** labels into the label table.
+*/
+#if defined(MR_STATIC_CODE_ADDRESSES) || defined(PROFILE_CALLS) \
+ || defined(DEBUG_LABELS) || defined(MR_INSERT_LABELS)
+ #define MR_NEED_INITIALIZATION_CODE
+#endif
+
#endif /* MERCURY_CONF_H */
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_goto.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_goto.h
--- mercury_goto.h 1998/01/06 07:05:59 1.5
+++ mercury_goto.h 1998/03/05 06:09:35
@@ -9,9 +9,9 @@
#ifndef MERCURY_GOTO_H
#define MERCURY_GOTO_H
+#include "mercury_conf.h"
#include "mercury_types.h" /* for `Code *' */
#include "mercury_debug.h" /* for debuggoto() */
-#include "mercury_accurate_gc.h"
#define paste(a,b) a##b
#define stringify(string) #string
@@ -19,10 +19,10 @@
#define skip(label) paste(skip_,label)
#ifdef MR_USE_STACK_LAYOUTS
- #define MR_STACK_LAYOUT(label) (Word *) (Word) \
+ #define MR_STACK_LAYOUT(label) (Word *) (Word) \
&(paste(mercury_data__stack_layout__,label))
#else
- #define MR_STACK_LAYOUT(label) (Word *) NULL
+ #define MR_STACK_LAYOUT(label) (Word *) NULL
#endif /* MR_USE_STACK_LAYOUTS */
@@ -34,24 +34,23 @@
** accurate garbage collection.
*/
-#if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(NATIVE_GC)
-#define make_label(n, a, l) /* nothing */
+#if !defined(MR_INSERT_LABELS)
+ #define make_label(n, a, l) /* nothing */
#else
-#define make_label(n, a, l) make_entry(n, a, l)
+ #define make_label(n, a, l) make_entry(n, a, l)
#endif
-#if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(PROFILE_CALLS) \
- && !defined(NATIVE_GC)
-#define make_local(n, a, l) /* nothing */
+#if !defined(MR_INSERT_LABELS) && !defined(PROFILE_CALLS)
+ #define make_local(n, a, l) /* nothing */
#else
-#define make_local(n, a, l) make_entry(n, a, l)
+ #define make_local(n, a, l) make_entry(n, a, l)
#endif
-#if defined(SPEED) && !defined(DEBUG_LABELS) && !defined(DEBUG_GOTOS) \
- && !defined(PROFILE_CALLS) && !defined(NATIVE_GC)
-#define make_entry(n, a, l) /* nothing */
+#if !defined(MR_INSERT_LABELS) && !defined(PROFILE_CALLS) \
+ && !defined(DEBUG_LABELS)
+ #define make_entry(n, a, l) /* nothing */
#else
-#define make_entry(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
+ #define make_entry(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
#endif
@@ -517,7 +516,7 @@
#define init_local(label) make_local(stringify(label), &&label, label)
#define Define_label(label) Define_local(label)
#define Declare_label(label) /* no declaration required */
- #ifdef NATIVE_GC
+ #ifdef MR_INSERT_LABELS
#define init_label(label) \
make_label(stringify(label), &&entry(label), label)
#else
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_grade.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_grade.h
--- mercury_grade.h 1997/12/05 15:56:31 1.5
+++ mercury_grade.h 1998/03/04 06:09:49
@@ -31,11 +31,11 @@
#define MR_PASTE2(p1,p2) MR_PASTE2_2(p1,p2)
#define MR_PASTE2_2(p1,p2) p1##p2
-/* paste 9 macros together */
-#define MR_PASTE10(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
- MR_PASTE10_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
-#define MR_PASTE10_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
- p1##p2##p3##p4##p5##p6##p7##p8##p9##p10
+/* paste 10 macros together */
+#define MR_PASTE11(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) \
+ MR_PASTE11_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11)
+#define MR_PASTE11_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) \
+ p1##p2##p3##p4##p5##p6##p7##p8##p9##p10##p11
/*
** Here we build up the MR_GRADE macro part at a time,
@@ -151,7 +151,19 @@
#define MR_GRADE_PART_10
#endif
-#define MR_GRADE MR_PASTE10( \
+/*
+** Stack traces aren't strictly binary incompatible - but if you
+** try to do a stack trace you might find it doesn't work very
+** well unless all modules are compiled in with --stack-trace.
+** Hence we consider it effectively binary incompatible.
+*/
+#if defined(MR_STACK_TRACE)
+ #define MR_GRADE_PART_11 _strce
+#else
+ #define MR_GRADE_PART_11
+#endif
+
+#define MR_GRADE MR_PASTE11( \
MR_GRADE_PART_1, \
MR_GRADE_PART_2, \
MR_GRADE_PART_3, \
@@ -161,7 +173,8 @@
MR_GRADE_PART_7, \
MR_GRADE_PART_8, \
MR_GRADE_PART_9, \
- MR_GRADE_PART_10 \
+ MR_GRADE_PART_10, \
+ MR_GRADE_PART_11 \
)
#define MR_GRADE_VAR MR_PASTE2(MR_grade_,MR_GRADE)
Index: runtime/mercury_ho_call.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_ho_call.c,v
retrieving revision 1.6
diff -u -r1.6 mercury_ho_call.c
--- mercury_ho_call.c 1998/02/12 01:25:54 1.6
+++ mercury_ho_call.c 1998/03/04 07:52:31
@@ -51,11 +51,8 @@
#define MR_CLASS_METHOD_CALL_INPUTS 4
Define_extern_entry(do_call_det_closure);
-Declare_label(det_closure_return);
Define_extern_entry(do_call_semidet_closure);
-Declare_label(semidet_closure_return);
Define_extern_entry(do_call_nondet_closure);
-Declare_label(nondet_closure_return);
Define_extern_entry(do_call_det_class_method);
Define_extern_entry(do_call_semidet_class_method);
@@ -71,14 +68,8 @@
Declare_label(mercury__compare_3_0_i1);
MR_MAKE_STACK_LAYOUT_ENTRY(do_call_det_closure);
-MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(det_closure_return,
- do_call_det_closure);
MR_MAKE_STACK_LAYOUT_ENTRY(do_call_semidet_closure);
-MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(semidet_closure_return,
- do_call_semidet_closure);
MR_MAKE_STACK_LAYOUT_ENTRY(do_call_nondet_closure);
-MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(nondet_closure_return,
- do_call_nondet_closure);
MR_MAKE_STACK_LAYOUT_ENTRY(do_call_det_class_method);
MR_MAKE_STACK_LAYOUT_ENTRY(do_call_semidet_class_method);
@@ -96,11 +87,8 @@
BEGIN_MODULE(call_module)
init_entry(do_call_det_closure);
- init_label(det_closure_return);
init_entry(do_call_semidet_closure);
- init_label(semidet_closure_return);
init_entry(do_call_nondet_closure);
- init_label(nondet_closure_return);
init_entry(do_call_det_class_method);
init_entry(do_call_semidet_class_method);
Index: runtime/mercury_imp.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_imp.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_imp.h
--- mercury_imp.h 1997/12/05 15:56:38 1.4
+++ mercury_imp.h 1998/02/19 05:22:03
@@ -41,7 +41,9 @@
#include "mercury_types.h"
#include "mercury_string.h"
#include "mercury_float.h"
+#include "mercury_stack_trace.h"
#include "mercury_accurate_gc.h"
+#include "mercury_stack_layout.h"
#include "mercury_tags.h"
#include "mercury_goto.h"
Index: runtime/mercury_type_info.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_type_info.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_type_info.h
--- mercury_type_info.h 1998/01/23 12:12:05 1.4
+++ mercury_type_info.h 1998/03/05 06:22:27
@@ -326,17 +326,6 @@
*/
/*
-** Static code addresses are available, unless using gcc non-local gotos,
-** without assembler labels.
-*/
-
-#if (defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS))
- #undef MR_STATIC_CODE_ADDRESSES
-#else
- #define MR_STATIC_CODE_ADDRESSES
-#endif
-
-/*
** Definitions for initialization of base_type_infos. If
** MR_STATIC_CODE_ADDRESSES are not available, we need to initialize
** the special predicates in the base_type_infos.
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/scripts/mgnuc.in,v
retrieving revision 1.47
diff -u -r1.47 mgnuc.in
--- mgnuc.in 1998/03/03 06:12:28 1.47
+++ mgnuc.in 1998/03/04 07:50:03
@@ -33,6 +33,7 @@
--pic-reg
--inline-alloc
--split-c-files
+ --stack-trace
See the documentation in the \"Invocation\" section
of the Mercury User's Guide.
@@ -140,6 +141,13 @@
SPLIT_OPTS=
;;
+ --stack-trace)
+ STACK_TRACE_OPTS=-DMR_STACK_TRACE
+ ;;
+ --no-stack-trace)
+ STACK_TRACE_OPTS=
+ ;;
+
--inline-alloc)
INLINE_ALLOC_OPTS="-DINLINE_ALLOC -DSILENT"
;;
@@ -343,26 +351,19 @@
exec $AS $AS_OPTS "$@" ;;
esac
-# please keep the three long lines below in sync
-case $verbose in true)
- echo $CC $ALL_C_INCL_DIRS $ANSI_OPTS $CHECK_OPTS \
- $GRADE_OPTS $GC_OPTS \
+
+ALL_CC_OPTS="$ANSI_OPTS $CHECK_OPTS $GRADE_OPTS $GC_OPTS \
$PROF_TIME_OPTS $PROF_CALLS_OPTS $PROF_MEMORY_OPTS \
$INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
- $PICREG_OPTS $ARCH_OPTS $ARG_OPTS \
- "$@" $OVERRIDE_OPTS ;;
+ $STACK_TRACE_OPTS $PICREG_OPTS $ARCH_OPTS $ARG_OPTS"
+
+case $verbose in true)
+ echo $CC -I$C_INCL_DIR -I$GC_INCL_DIR \
+ $ALL_CC_OPTS "$@" $OVERRIDE_OPTS ;;
esac
case $# in
- 0) exec $CC $ALL_C_INCL_DIRS $ANSI_OPTS $CHECK_OPTS \
- $GRADE_OPTS $GC_OPTS \
- $PROF_TIME_OPTS $PROF_CALLS_OPTS $PROF_MEMORY_OPTS \
- $INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
- $PICREG_OPTS $ARCH_OPTS $ARG_OPTS \
- $OVERRIDE_OPTS ;;
- *) exec $CC $ALL_C_INCL_DIRS $ANSI_OPTS $CHECK_OPTS \
- $GRADE_OPTS $GC_OPTS \
- $PROF_TIME_OPTS $PROF_CALLS_OPTS $PROF_MEMORY_OPTS \
- $INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
- $PICREG_OPTS $ARCH_OPTS $ARG_OPTS \
- "$@" $OVERRIDE_OPTS ;;
+ 0) exec $CC -I$C_INCL_DIR -I$GC_INCL_DIR \
+ $ALL_CC_OPTS $OVERRIDE_OPTS ;;
+ *) exec $CC -I$C_INCL_DIR -I$GC_INCL_DIR \
+ $ALL_CC_OPTS "$@" $OVERRIDE_OPTS ;;
esac
Index: util/mkinit.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/util/mkinit.c,v
retrieving revision 1.26
diff -u -r1.26 mkinit.c
--- mkinit.c 1998/02/03 08:20:12 1.26
+++ mkinit.c 1998/03/05 06:32:17
@@ -174,10 +174,7 @@
static const char if_need_to_init[] =
- "#if (defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS)) \\\n"
- " || defined(PROFILE_CALLS) || defined(DEBUG_GOTOS) \\\n"
- " || defined(DEBUG_LABELS) || defined(NATIVE_GC) \\\n"
- " || !defined(SPEED)\n\n"
+ "#if defined(MR_NEED_INITIALIZATION_CODE)\n\n"
;
New File: runtime/mercury_stack_layout.h
===================================================================
/*
** 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.
*/
#ifndef MERCURY_STACK_LAYOUT_H
#define MERCURY_STACK_LAYOUT_H
/*
** mercury_stack_layout.h -
** Definitions for the stack layout data structures.
*/
/*
** Definitions for MR_PredFunc
*/
typedef enum { MR_PREDICATE, MR_FUNCTION } MR_PredFunc;
/*
** Definitions for MR_Determinism
**
** The max_soln component of the determinism is encoded in the 1 and 2 bits.
** The can_fail component of the determinism is encoded in the 4 bit.
** The first_solution component of the determinism is encoded in the 8 bit.
**
** MR_DETISM_AT_MOST_MANY could also be defined as ((d) & 3) == 3),
** but this would be less efficient, since the C compiler does not know
** that we do not set the 1 bit unless we also set the 2 bit.
*/
typedef Word MR_Determinism;
#define MR_DETISM_DET 6
#define MR_DETISM_SEMI 2
#define MR_DETISM_NON 3
#define MR_DETISM_MULTI 7
#define MR_DETISM_ERRONEOUS 4
#define MR_DETISM_FAILURE 0
#define MR_DETISM_CCNON 10
#define MR_DETISM_CCMULTI 14
#define MR_DETISM_AT_MOST_ZERO(d) (((d) & 3) == 0)
#define MR_DETISM_AT_MOST_ONE(d) (((d) & 3) == 2)
#define MR_DETISM_AT_MOST_MANY(d) (((d) & 1) != 0)
#define MR_DETISM_CAN_FAIL(d) (((d) & 4) != 0)
#define MR_DETISM_FIRST_SOLN(d) (((d) & 8) != 0)
#define MR_DETISM_DET_CODE_MODEL(d) (((d) & 1) == 0)
/*
** Definitions for "MR_Live_Lval"
**
** MR_Live_Lval is a Word which describes an lval. This includes:
** - 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
** data field describing which stack slot number or register number.
**
** Lval Tag Rest
** r(Num) 0 Num
** f(Num) 1 Num
** stackvar(Num) 2 Num
** framevar(Num) 3 Num
** succip 4
** maxfr 5
** curfr 6
** hp 7
** sp 8
** unknown 9 (The location is not known)
**
** The type MR_Lval_Type describes the different tag values.
**
** This data is generated in compiler/stack_layout.m, which must be kept
** in sync with the constants defined here.
*/
typedef Word MR_Live_Lval;
typedef enum {
MR_LVAL_TYPE_R,
MR_LVAL_TYPE_F,
MR_LVAL_TYPE_STACKVAR,
MR_LVAL_TYPE_FRAMEVAR,
MR_LVAL_TYPE_SUCCIP,
MR_LVAL_TYPE_MAXFR,
MR_LVAL_TYPE_CURFR,
MR_LVAL_TYPE_HP,
MR_LVAL_TYPE_SP,
MR_LVAL_TYPE_UNKNOWN
} MR_Lval_Type;
#define MR_LIVE_LVAL_TAGBITS 8
#define MR_LIVE_LVAL_TYPE(Lval) \
((MR_Lval_Type) (((Word) Lval) & ((1 << MR_LIVE_LVAL_TAGBITS) - 1)))
#define MR_LIVE_LVAL_NUMBER(Lval) \
((int) ((Word) Lval) >> MR_LIVE_LVAL_TAGBITS)
/*
** Definitions for MR_Live_Type
**
** MR_Live_Type describes live data. This includes:
** - succip, hp, curfr, maxfr, redoip, and
** mercury data values (vars).
**
** 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,
** containing a type_info and an instantiation represention.
**
** This data is generated in compiler/stack_layout.m, which must be kept
** in sync with the constants defined here.
*/
typedef Word MR_Live_Type;
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_Lval_NonVar;
typedef struct {
Word type;
Word inst;
} MR_Var_Shape_Info;
#define MR_LIVE_TYPE_IS_VAR(T) ( (Word) T > TYPELAYOUT_MAX_VARINT )
#define MR_LIVE_TYPE_GET_NONVAR(T) \
((MR_Lval_NonVar) T)
#define MR_LIVE_TYPE_GET_VAR_TYPE(T) \
((Word) ((MR_Var_Shape_Info *) T)->type)
#define MR_LIVE_TYPE_GET_VAR_INST(T) \
((Word) ((MR_Var_Shape_Info *) T)->inst)
/*
** Macros to support hand-written C code.
*/
/*
** Define a stack layout for a label that you know very little about.
** It's just a generic entry label, no useful information, except
** the code address for the label.
*/
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_ENTRY(l) \
const struct mercury_data__stack_layout__##l##_struct { \
Code * f1; \
Integer f2; \
Integer f3; \
Integer f4; \
} mercury_data__stack_layout__##l = { \
STATIC(l), \
(Integer) -1, /* Unknown determinism */ \
(Integer) -1, /* Unknown number of stack slots */ \
(Integer) MR_LVAL_TYPE_UNKNOWN /* Unknown succip location */ \
};
#else
#define MR_MAKE_STACK_LAYOUT_ENTRY(l)
#endif /* MR_USE_STACK_LAYOUTS */
/*
** Define a stack layout for an internal label. Need to supply the
** label name (l) and the entry label name (e).
**
** The only useful information in this structure is the code address
** and the reference to the entry for this label.
*/
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e) \
const struct mercury_data__stack_layout__##l##_struct { \
const Word * f1; \
Integer f2; \
const Word * f3; \
} mercury_data__stack_layout__##l = { \
(const Word *) &mercury_data__stack_layout__##e, \
(Integer) -1, /* Unknown number of live values */ \
(const Word *) NULL /* No list of live valeus */ \
};
#else
#define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)
#endif /* MR_USE_STACK_LAYOUTS */
/*
** Define a stack layout for an internal label.
** Need to supply the label name (l) and the number (x), eg for
** label_name_i3, x is 3. It is assumed the entry label for that
** corresponds to this label is the label name without the _iX suffix.
**
** (MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY, above, is a little
** more general than MR_MAKE_STACK_LAYOUT_INTERNAL. This macro can
** only describe relationships between labels that have the same
** base -- MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY can create layouts
** for internal labels no matter what the name of the entry layout is).
**
** The only useful information in this structure is the code address
** and the reference to the entry for this label.
*/
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_INTERNAL(e, x) \
const struct mercury_data__stack_layout__##e##_i##x##_struct { \
const Word * f1; \
Integer f2; \
const Word * f3; \
} mercury_data__stack_layout__##e##_i##x = { \
(const Word *) &mercury_data__stack_layout__##e, \
(Integer) -1, /* Unknown number of live values */ \
(const Word *) NULL /* No list of live valeus */ \
};
#else
#define MR_MAKE_STACK_LAYOUT_INTERNAL(l, x)
#endif /* MR_USE_STACK_LAYOUTS */
/*
** Structs and macros to support stack layouts.
*/
typedef struct MR_stack_layout_shape_struct {
Word *MR_sls_type;
Word MR_sls_inst;
} MR_stack_layout_shape;
typedef struct MR_stack_layout_var_struct {
Integer MR_slv_locn;
MR_stack_layout_shape *MR_slv_shape;
} MR_stack_layout_var;
typedef struct MR_stack_layout_vars_struct {
MR_stack_layout_var *MR_slvs_pairs;
String *MR_slvs_names;
Word *MR_slvs_tvars;
} MR_stack_layout_vars;
typedef struct MR_stack_layout_entry_struct {
Code *MR_sle_code_addr;
MR_Determinism MR_sle_detism;
Integer MR_sle_stack_slots;
MR_Live_Lval MR_sle_succip_locn;
/* the fields from here onwards are present only with procid layouts */
MR_PredFunc MR_sle_pred_or_func;
String MR_sle_decl_module;
String MR_sle_def_module;
String MR_sle_name;
Integer MR_sle_arity;
Integer MR_sle_mode;
/* the fields from here onwards are present only with trace layouts */
Integer MR_sle_in_arg_count;
MR_stack_layout_vars MR_sle_in_arg_info;
Integer MR_sle_out_arg_count;
MR_stack_layout_vars MR_sle_out_arg_info;
} MR_stack_layout_entry;
typedef struct MR_stack_layout_label_struct {
MR_stack_layout_entry *MR_sll_entry;
Integer MR_sll_var_count;
/* the last field is present only if MR_sll_var_count > 0 */
MR_stack_layout_vars MR_sll_var_info;
} MR_stack_layout_label;
/* The following macros support obsolete code. */
#define MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(s) \
((Code *) field(0, (s), 0))
#define MR_CONT_STACK_LAYOUT_GET_ENTRY_LAYOUT(s) \
(field(0, (s), 0))
#define MR_ENTRY_STACK_LAYOUT_GET_NUM_SLOTS(s) \
(field(0, (s), 2))
#define MR_ENTRY_STACK_LAYOUT_GET_CODE_MODEL(s) \
(field(0, (s), 1) & 1)
#define MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(s) \
(field(0, (s), 3))
/*---------------------------------------------------------------------------*/
#endif /* not MERCURY_STACK_LAYOUT_H */
New File: runtime/mercury_stack_trace.c
===================================================================
/*
** 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_stack_trace.c - implements stack traces.
**
** Main author: Tyson Dowd <trd at cs.mu.oz.au>.
*/
#include "mercury_imp.h"
#include "mercury_stack_trace.h"
#include <stdio.h>
void
MR_dump_stack(Code *success_pointer, Word *det_stack_pointer)
{
Label *label;
MR_Live_Lval location;
MR_stack_layout_label *layout;
MR_stack_layout_entry *entry_layout;
MR_Lval_Type type;
int number, determinism;
#ifndef MR_STACK_TRACE
fprintf(stderr, "Stack dump not available in this grade.\n");
#else
fprintf(stderr, "Stack dump follows (determinisitic stack only):\n");
do {
label = lookup_label_addr(success_pointer);
if (label == NULL) {
fatal_error("internal label not found");
}
layout = (MR_stack_layout_label *) label->e_layout;
entry_layout = layout->MR_sll_entry;
label = lookup_label_addr(
entry_layout->MR_sle_code_addr);
if (label == NULL) {
fatal_error("entry label not found");
}
location = entry_layout->MR_sle_succip_locn;
type = MR_LIVE_LVAL_TYPE(location);
number = MR_LIVE_LVAL_NUMBER(location);
determinism = entry_layout->MR_sle_detism;
if (MR_DETISM_DET_CODE_MODEL(determinism)) {
fprintf(stderr, "\t%s\n", label->e_name);
if (type == MR_LVAL_TYPE_STACKVAR) {
success_pointer = (Code *) field(0,
det_stack_pointer, -number);
} else {
fatal_error("can only handle stackvars");
}
det_stack_pointer = det_stack_pointer -
entry_layout->MR_sle_stack_slots;
}
} while (MR_DETISM_DET_CODE_MODEL(determinism));
#endif /* MR_STACK_TRACE */
}
New File: runtime/mercury_stack_trace.h
===================================================================
/*
** 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.
*/
#ifndef MERCURY_STACK_TRACE_H
#define MERCURY_STACK_TRACE_H
/*
** mercury_stack_trace.h -
** Definitions for use by the stack tracing.
*/
/*---------------------------------------------------------------------------*/
/*
** MR_dump_stack:
** Given the succip and det stack pointer, generate a stack dump
** showing then name of each procedure on the stack.
** XXX
** Currently only deterministic stack frames are handled, if a
** nondeterministic stack frame is found while tracing down the
** stack, the stack dump ends.
*/
extern void MR_dump_stack(Code *success_pointer, Word *det_stack_pointer);
#endif /* MERCURY_STACK_TRACE_H */
--
Tyson Dowd # There isn't any reason why Linux can't be
# implemented as an enterprise computing solution.
trd at cs.mu.oz.au # Find out what you've been missing while you've
http://www.cs.mu.oz.au/~trd # been rebooting Windows NT. -- InfoWorld, 1998.
More information about the developers
mailing list