for review: fix for stack traces in -O-1
Tyson Dowd
trd at cs.mu.OZ.AU
Wed Apr 8 16:02:42 AEST 1998
Hi,
Mark, want to review this one?
(Mark reported this bug, so he gets the honour of seeing it fixed.
Isn't he lucky?).
===================================================================
Estimated hours taken: 3
Fix stack traces dying in -O-1.
error/1 is usually generated with no stack frame, but in -O-1 it is
generated with one (but doesn't need it). error/1 passes
MR_dump_stack MR_succip and MR_sp, and MR_dump_stack assumes that
MR_succip is for the topmost stack frame, but if error/1 has a stack
frame, this is not true.
library/require.m:
Make sure the caller of MR_dump_stack has no stack frame
by using handwritten code. We call the handwritten code
from error/1, and so we have the nice side effect that
error now appears in the stack dump.
runtime/mercury_stack_trace.h:
Document that MR_dump_stack assumes the succip is for the
topmost stack frame.
Index: library/require.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/require.m,v
retrieving revision 1.19
diff -u -r1.19 require.m
--- require.m 1998/04/07 05:13:30 1.19
+++ require.m 1998/04/07 09:08:07
@@ -55,14 +55,41 @@
% Hopefully error/1 won't be called often (!), so no point inlining it.
:- pragma no_inline(error/1).
-:- pragma c_code(error(Message::in), "
+error(Message) :-
+ error_internal(Message).
+
+:- pred error_internal(string::in) is erroneous.
+
+% We define error using handwritten code in error_internal because we
+% need complete control over it if we want to call MR_dump_stack. In
+% particular we don't want to have to explicitly tell MR_dump_stack whether
+% a stack frame was generated by its caller. The easiest way to do
+% this is to make sure it wasn't.
+
+:- external(error_internal/1).
+
+:- pragma c_code("
+
+Define_extern_entry(mercury__require__error_internal_1_0);
+
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__require__error_internal_1_0);
+
+BEGIN_MODULE(require_module_internal)
+ init_entry(mercury__require__error_internal_1_0);
+BEGIN_CODE
+
+/* code for predicate 'error'/1 in mode 0 */
+Define_entry(mercury__require__error_internal_1_0);
+{
+ String Message;
+ Message = (String) r1;
+
fflush(stdout);
fprintf(stderr, ""Software error: %s\\n"", Message);
MR_dump_stack(MR_succip, MR_sp, MR_curfr);
exit(1);
-#ifndef USE_GCC_NONLOCAL_GOTOS
- return 0; /* suppress some dumb warnings */
-#endif
+}
+END_MODULE
").
:- end_module require.
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_stack_trace.h
--- mercury_stack_trace.h 1998/04/07 05:23:07 1.2
+++ mercury_stack_trace.h 1998/04/07 09:12:14
@@ -16,8 +16,21 @@
/*
** MR_dump_stack:
-** Given the succip and det stack pointer, generate a stack dump
-** showing then name of each active procedure on the stack.
+** Given the succip, det stack pointer and current frame, generate a
+** stack dump showing then name of each active procedure on the
+** stack.
+** NOTE: MR_dump_stack will assume that the succip is for the
+** topmost stack frame. If you call MR_dump_stack from some
+** pragma c_code that may not be the case.
+** Due to some optimizations (or lack thereof) the MR_dump_stack call
+** may end up inside code that has a stack frame allocated, but a
+** has a succip for the previous stack frame.
+** Don't call MR_dump_stack from Mercury pragma c_code (calling
+** from other C code in the runtime is probably ok, provided the
+** succip corresponds to the topmost stack frame).
+** If you need more convienent calling from Mercury code, it would
+** probably be best to make an impure predicate defined as using
+** `:- external'.
*/
extern void MR_dump_stack(Code *success_pointer, Word *det_stack_pointer,
--
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