mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
Fergus's recent change to the handling of some builtins broke the tracing
Estimated hours taken: 20 Fergus's recent change to the handling of some builtins broke the tracing of those builtins. The following changes are a fix for this. compiler/polymorphism.m: Export the predicate that checks whether a predicate is a builtin that lacks the usually necessary typeinfos. Comment out a misleading and in any case not very useful progress message. compiler/liveness.m: Turn off type_info liveness for builtins without typeinfos. Since these builtins establish no gc points and shouldn't be execution traced, this is OK. Make type_info liveness part of live_info, since it can now be incorrect to look up the value of the option. (This may yield a speedup.) compiler/live_vars.m: compiler/store_alloc.m: Pass the pred_id to initial_liveness to liveness.m can do the test. compiler/passes_aux.m: Add a new traversal type that passes along the pred_id. compiler/mercury_compile.m: Turn off execution tracing for the modules builtin.m and private_builtin.m. The latter contains the interface predicates for the builtins without typeinfos. Since the interface predicates also lack the typeinfos, the compiler would get an internal abort if we left execution tracing on. In any case, these two modules contain stuff that users should consider language builtins, which means they should not be execution traced (they can still be stack traced in the right grade). Use the new traversal type for the modules that now need the pred_id. compiler/globals.m: Allow the trace level to be set from outside, in this case mercury_compile.m. The next batch of changes have to do with adding a stack dump command to the debugger. Since debugging is possible even in non-debug grades, this in turn requires allowing stack tracing to work in non-debug grades, on programs in which only some modules are compiled with execution (and hence stack) tracing. compiler/llds_out.m: compiler/mercury_compile.m: runtime/mercury_conf_param.h: Llds_out used to output "#include <mercury_imp.h>" as the first substantive thing in the generated C file. The set of #define parameters in effect when mercury_imp.h is processed determines whether the macros that optionally register stack layouts for label actually do so or not. The values of these parameters are derived from the grade, which means that with this setup it is not possible for a non-debug grade program to register its stack layouts in the label table. The new version of llds_out looks up the option that says whether this module is compiled with execution tracing or not, and if it is, it generates a #define MR_STACK_TRACE_THIS_MODULE *before* the #include of mercury_imp.h. This causes mercury_conf_param.h, included from mercury_imp.h, to define the macros MR_USE_STACK_LAYOUTS and and MR_INSERT_LABELS, which in turn cause stack layouts for labels in this module to be generated and to be inserted into the label table, *without* changing the grade string (this last part is why we do not simply define MR_STACK_TRACE). Use the same mechanism to #include mercury_trace.h when doing execution tracing, since it is simpler than the mechanism we used to use (mercury_compile.m including the #include in a list of C header file fragments). compiler/mercury_compile.m: runtime/mercury_conf_param.h: Split the MR_NEED_INITIALIZATION_CODE macro into two parts. The first, MR_MAY_NEED_INITIALIZATION, now controls whether initialization code makes it into the object file of a module. The second, MR_NEED_INITIALIZATION_AT_START, determines whether the initialization code is called before main/2. When a module is compiled with execution tracing, the macro MR_INSERT_LABELS turns on MR_MAY_NEED_INITIALIZATION but not MR_NEED_INITIALIZATION_AT_START. The debugger will make sure that the initialization code has been called before it tries to do a stack dump (which needs the initialization code to have been executed, because it needs labels to have been put into the label table so that from a return address it can find the layout of the proc to which it belongs). Define MR_NEED_INITIALIZATION_AT_START if PROFILE_TIME is defined, since if PROFILE_TIME is defined mercury_wrapper.c calls init_modules. The fact that MR_NEED_INITIALIZATION_CODE didn't used to be defined when PROFILE_TIME was defined was, I believe, a bug, which was not detected because we do not turn on PROFILE_TIME without also turning on PROFILE_CALLS. runtime/mercury_stack_trace.[ch]: Change the way stack dumps are done, to make it possible to print stack dumps from the debugger and to use trivial run-length encoding on the output (so that 100 consecutive calls to p yield the line "p * 100", rather than 100 lines of "p"). The stack routine now returns an indication of whether the stack dump was fully successful, and if not, a description of the reason why not. This requires knowing when we have found the end of the stack dump, so we provide a global variable, MR_stack_trace_bottom, which mercury_wrapper.c will set to global_success, the address main/2 goes to on success. s/multidet/multi/ runtime/mercury_wrapper.c: Set MR_stack_trace_bottom to the address of globals_success. Use MR_NEED_INITIALIZATION_AT_START to decide whether to call do_init_modules. runtime/mercury_stacks.h: Provide variants of detstackvar(n) and framevar(n) that look up sp and curfr in an array of saved regs, for use by the debugger. runtime/mercury_trace_util.c: Use the new variants of detstackvar(n) and framevar(n). This fixes an old bug on SPARCs. runtime/mercury_trace_internal.c: Completely reorganize the way debugger commands are handled. Centralize reading in command lines, and the breaking up of command lines into words. The command names are the same as they were, but command syntax is now much easier to change. Add a new command "d" to dump as much of the stack as the available information will allow. runtime/mercury_goto.h: Cosmetic changes to avoid the use of two different conditional compilation layout styles. util/mkinit.c: Since we cannot know when we generate the _init.c file whether any modules will be compiled with execution tracing and will thus need stack tracing, we must now include in the generated _init.c file the code to call the initialization functions in all the modules, even if MR_NEED_INITIALIZATION_AT_START is not set, since init_modules can be called later, from the debugger. (We should be able to use the same approach with the accurate collector.)
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#ifndef MERCURY_STACK_TRACE_H
|
||||
#define MERCURY_STACK_TRACE_H
|
||||
|
||||
#include "mercury_stack_layout.h"
|
||||
|
||||
/*
|
||||
** mercury_stack_trace.h -
|
||||
** Definitions for use by the stack tracing.
|
||||
@@ -21,7 +23,7 @@
|
||||
** 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.
|
||||
** 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
|
||||
** that has a succip for the previous stack frame.
|
||||
@@ -35,7 +37,30 @@
|
||||
** 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:
|
||||
** This function does the same job and makes the same assumptions
|
||||
** as MR_dump_stack, but instead of the succip, it takes the entry
|
||||
** layout of the current procedure as input. It also takes a parameter
|
||||
** that tells it where to put the stack dump. If the entire stack
|
||||
** was printed successfully, the return value is NULL; otherwise,
|
||||
** it is a string indicating why the dump was cut short.
|
||||
*/
|
||||
|
||||
extern const char *MR_dump_stack_from_layout(FILE *fp,
|
||||
MR_Stack_Layout_Entry *entry_layout,
|
||||
Word *det_stack_pointer, Word *current_frame);
|
||||
|
||||
/*
|
||||
** 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;
|
||||
|
||||
#endif /* MERCURY_STACK_TRACE_H */
|
||||
|
||||
Reference in New Issue
Block a user