for review: stack dumps.
Tyson Dowd
trd at cs.mu.OZ.AU
Tue Mar 3 19:16:44 AEDT 1998
Hi,
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 = -DMR_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:
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: 8
Add support for stack dumps, do a stack dump from error/1.
library/require.m:
Call MR_dump_stack if error is called.
runtime/Mmakefile:
runtime/mercury_imp.h:
runtime/mercury_init.h:
Add new files.
runtime/mercury_accurate_gc.h:
Remove stack_layout stuff, leave this file for accurate
GC specific definitions.
Define MR_INSERT_LABELS if doing NATIVE_GC.
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_INSERT_LABELS 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.
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 06:12:41
@@ -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);
+ dump_stack(MR_succip, MR_sp);
exit(1);
#ifndef USE_GCC_NONLOCAL_GOTOS
return 0; /* suppress some dumb warnings */
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/01 03:38:32
@@ -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.4
diff -u -r1.4 mercury_accurate_gc.h
--- mercury_accurate_gc.h 1998/01/06 07:05:56 1.4
+++ mercury_accurate_gc.h 1998/02/19 05:26:36
@@ -15,219 +15,10 @@
/*---------------------------------------------------------------------------*/
-/*
-** 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
+ #define MR_INSERT_LABELS
#endif
-
-/*
-** Definitions for MR_Stack_Specifier
-*/
-
-typedef enum { MR_STACK_DET, MR_STACK_NONDET } MR_Stack_Specifier;
-
-/*
-** 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 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 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 number of stack slots */ \
- (Integer) -1, /* Unknown code model */ \
- (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 */
-
-
-/*
-** Macros to support stack layouts.
-** XXX ought to use a MR_Entry_Stack_Layout and MR_Cont_Stack_Layout
-** struct to make it easier to access the fields.
-*/
-
-#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), 1))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_CODE_MODEL(s) \
- (field(0, (s), 2))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(s) \
- (field(0, (s), 3))
/*---------------------------------------------------------------------------*/
#endif /* not MERCURY_ACCURATE_GC_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/02/19 05:21:38
@@ -11,6 +11,7 @@
#include "mercury_types.h" /* for `Code *' */
#include "mercury_debug.h" /* for debuggoto() */
+#include "mercury_stack_trace.h"
#include "mercury_accurate_gc.h"
#define paste(a,b) a##b
@@ -34,21 +35,21 @@
** accurate garbage collection.
*/
-#if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(NATIVE_GC)
+#if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(MR_INSERT_LABELS)
#define make_label(n, a, l) /* nothing */
#else
#define make_label(n, a, l) make_entry(n, a, l)
#endif
#if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(PROFILE_CALLS) \
- && !defined(NATIVE_GC)
+ && !defined(MR_INSERT_LABELS)
#define make_local(n, a, l) /* nothing */
#else
#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)
+ && !defined(PROFILE_CALLS) && !defined(MR_INSERT_LABELS)
#define make_entry(n, a, l) /* nothing */
#else
#define make_entry(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
@@ -517,7 +518,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_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_init.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_init.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_init.h
--- mercury_init.h 1997/11/23 07:21:25 1.2
+++ mercury_init.h 1998/02/19 03:51:32
@@ -88,6 +88,9 @@
#include "gc.h"
#endif
+#include "mercury_stack_trace.h"
+#include "mercury_accurate_gc.h"
+
/*
** mercury_main() takes the address of the following predicates/functions,
** which are defined elsewhere.
Index: util/mkinit.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/util/mkinit.c,v
retrieving revision 1.25
diff -u -r1.25 mkinit.c
--- mkinit.c 1997/12/03 07:28:15 1.25
+++ mkinit.c 1998/02/19 03:49:27
@@ -174,7 +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(DEBUG_LABELS) || defined(MR_INSERT_LABELS) \\\n"
" || !defined(SPEED)\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.
*/
/*---------------------------------------------------------------------------*/
/*
** 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.
*/
/*
** Definitions for MR_Stack_Specifier
*/
typedef enum { MR_STACK_DET, MR_STACK_NONDET } MR_Stack_Specifier;
/*
** 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 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 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)
/*
** MR_Determinsim encodes the determinism using properties of the
** determinsim. The bit encoding is done in stack_layout.m, changes
** here will need to be reflected there.
*/
typedef Word MR_Determinsim;
/*
** A det code model is any code model where there is at most one
** solution. The 1st bit is set is there is more than one
** solution.
*/
#define MR_DETERMINSIM_IS_DET_CODE_MODEL(detism) \
(!((detism) & 1))
/*
** 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 number of stack slots */ \
(Integer) -1, /* Unknown code model */ \
(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 */
/*
** Macros to support stack layouts.
** XXX ought to use a MR_Entry_Stack_Layout and MR_Cont_Stack_Layout
** struct to make it easier to access the fields.
*/
#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_DETERMINISM(s) \
(field(0, (s), 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 dump_stack(Code *success_pointer, Word *stack_pointer)
{
Label *label;
Word layout, entry_layout, location;
MR_Lval_Type type;
int number, determinisim;
#ifndef MR_USE_STACK_LAYOUTS
fprintf(stderr, "Stack dump not available in this grade.\n");
#else
fprintf(stderr, "Stack dump follows:\n");
do {
label = lookup_label_addr(success_pointer);
if (label == NULL) {
fatal_error("internal label not found");
}
layout = (Word) label->e_layout;
entry_layout = MR_CONT_STACK_LAYOUT_GET_ENTRY_LAYOUT(layout);
label = lookup_label_addr(
MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(entry_layout));
if (label == NULL) {
fatal_error("entry label not found");
}
location = MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(entry_layout);
type = MR_LIVE_LVAL_TYPE(location);
number = MR_LIVE_LVAL_NUMBER(location);
determinisim = MR_ENTRY_STACK_LAYOUT_GET_DETERMINISM(
entry_layout);
if (MR_DETERMINSIM_IS_DET_CODE_MODEL(determinisim)) {
fprintf(stderr, "\t%s\n", label->e_name);
if (type == MR_LVAL_TYPE_STACKVAR) {
success_pointer = (Code *) field(0,
stack_pointer, -number);
} else {
fatal_error("can only handle stackvars");
}
stack_pointer = stack_pointer -
MR_ENTRY_STACK_LAYOUT_GET_NUM_SLOTS(
entry_layout);
}
} while (MR_DETERMINSIM_IS_DET_CODE_MODEL(determinisim));
#endif /* MR_USE_STACK_LAYOUTS */
}
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.
*/
/*---------------------------------------------------------------------------*/
#ifdef MR_STACK_TRACE
#define MR_USE_STACK_LAYOUTS
#define MR_INSERT_LABELS
#endif
extern void dump_stack(Code *success_pointer, Word *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