mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-27 07:14:20 +00:00
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
315 lines
14 KiB
C
315 lines
14 KiB
C
// vim: ts=4 sw=4 expandtab ft=c
|
|
|
|
// Copyright (C) 1999-2008, 2011 The University of Melbourne.
|
|
// Copyright (C) 2015-2016, 2018 The Mercury team.
|
|
// This file is distributed under the terms specified in COPYING.LIB.
|
|
|
|
// This module looks after the debugger's information about the variables
|
|
// that are live at a given program point.
|
|
//
|
|
// When execution arrives at an event, the debugger should call the function
|
|
// MR_trace_init_point_vars to initialize this module's data structures
|
|
// to reflect the variables that are live at that event. During the processing
|
|
// of the various debugger commands while at that event, the debugger may
|
|
// call MR_trace_set_level or its MR_trace_set_level_from_layout variant
|
|
// zero or more times to change this module's notion of the "current" set
|
|
// of variables to refer instead to the variables that are live at the
|
|
// return address in a given ancestor. This module maintains its own record
|
|
// of what the current ancestor level is; the enquiry function
|
|
// MR_trace_current_level returns this information, while enquiry function
|
|
// MR_trace_current_level_details returns information about this level.
|
|
// Ancestor level 0 means the environment of the procedure call that generated
|
|
// the event.
|
|
//
|
|
// The debugger partitions the variables at a program point into three sets
|
|
// based on their type: those which are always printed, those which are always
|
|
// ignored (saved succips, void variables etc), and those which are optionally
|
|
// printed (typeinfos and typeclassinfos). The print_optionals argument of
|
|
// the following functions should be MR_TRUE iff you wish to print variables
|
|
// in the third set.
|
|
//
|
|
// The functions MR_trace_var_count, MR_trace_list_vars,
|
|
// MR_trace_return_var_info, MR_trace_headvar_num, MR_trace_parse_var_path,
|
|
// MR_trace_parse_browse_one, MR_trace_browse_one and MR_trace_browse_all
|
|
// all work in the context established by MR_trace_init_point_vars and
|
|
// possibly MR_trace_set_level.
|
|
//
|
|
// This context may say that there is no information available about
|
|
// the variables live at the current location (this is possible if the
|
|
// relevant module was not compiled with the right debugging flags).
|
|
// If this is the case, or if some other reason prevents these functions
|
|
// from carrying out their assigned tasks, most of these functions return
|
|
// a non-NULL string describing the problem; they return NULL if everything
|
|
// went OK. (MR_trace_set_level also returns a pointer to an error message
|
|
// -and refuses to change levels- if something goes wrong.)
|
|
|
|
#ifndef MERCURY_TRACE_VARS_H
|
|
#define MERCURY_TRACE_VARS_H
|
|
|
|
#include "mercury_types.h" // for MR_Word etc
|
|
#include "mercury_stack_layout.h" // for MR_LabelLayout etc
|
|
#include "mercury_type_info.h" // for MR_TypeInfo
|
|
#include "mercury_trace_base.h" // for MR_TracePort
|
|
#include "mercury_trace_browse.h" // for MR_Browser
|
|
#include "mercury_trace_completion.h" // for MR_CompleterList
|
|
#include <stdio.h>
|
|
|
|
typedef void (*MR_Browser)(MR_Word type_info, MR_Word value,
|
|
MR_BrowseCallerType caller, MR_BrowseFormat format);
|
|
|
|
typedef void (*MR_GoalBrowser)(MR_ConstString name, MR_Word arg_list,
|
|
MR_Word is_func, MR_BrowseCallerType caller,
|
|
MR_BrowseFormat format);
|
|
|
|
typedef enum {
|
|
MR_VAR_SPEC_NUMBER,
|
|
MR_VAR_SPEC_NAME,
|
|
MR_VAR_SPEC_HELD_NAME,
|
|
MR_VAR_SPEC_ATTRIBUTE
|
|
} MR_VarSpecKind;
|
|
|
|
typedef struct {
|
|
MR_VarSpecKind MR_var_spec_kind;
|
|
MR_Unsigned MR_var_spec_number; // valid if NUMBER
|
|
const char *MR_var_spec_name; // valid if NAME, HELD_NAME
|
|
// or ATTRIBUTE
|
|
} MR_VarSpec;
|
|
|
|
// This function converts a variable name or variable number to MR_VarSpec
|
|
// format.
|
|
|
|
extern void MR_convert_arg_to_var_spec(const char *word_spec,
|
|
MR_VarSpec *var_spec);
|
|
|
|
// Print the given MR_VarSpec.
|
|
|
|
extern void MR_print_var_spec(FILE *fp, MR_VarSpec *var_spec);
|
|
|
|
// These functions are documented near the top of this file.
|
|
|
|
extern void MR_trace_init_point_vars(const MR_LabelLayout *top_layout,
|
|
MR_Word *saved_regs, MR_Float *saved_f_regs,
|
|
MR_TracePort port, MR_bool print_optionals);
|
|
extern const char *MR_trace_set_level(int ancestor_level,
|
|
MR_bool print_optionals);
|
|
extern const char *MR_trace_set_level_from_layout(
|
|
const MR_LabelLayout *level_layout,
|
|
MR_Word *base_sp, MR_Word *base_curfr,
|
|
int ancestor_level, MR_bool print_optionals);
|
|
extern int MR_trace_current_level(void);
|
|
extern void MR_trace_current_level_details(
|
|
const MR_ProcLayout **entry_ptr,
|
|
const char **filename_ptr, int *linenumber_ptr,
|
|
MR_Word **base_sp_ptr, MR_Word **base_curfr_ptr);
|
|
|
|
// Return the number of live variables at the current point. If the required
|
|
// information is missing, return a negative number.
|
|
|
|
extern int MR_trace_var_count(void);
|
|
|
|
// Print the list of the names of variables live at the current point
|
|
// on the given file.
|
|
|
|
extern const char *MR_trace_list_vars(FILE *out);
|
|
|
|
// Print all the information this module has on the variables live
|
|
// at the current point on the given file. Intended only for debugging
|
|
// the debugger itself.
|
|
|
|
extern const char *MR_trace_list_var_details(FILE *out);
|
|
|
|
// Return as a side effect the name, type and value of the variable with the
|
|
// specified HLDS number, in the specified locations, all of which must be
|
|
// non-NULL. If the variable isn't live or isn't known, return a non-null
|
|
// string giving the problem.
|
|
|
|
extern const char *MR_trace_return_hlds_var_info(int hlds_num,
|
|
MR_TypeInfo *type_info_ptr, MR_Word *value_ptr);
|
|
|
|
// Return as a side effect the name, type and value of the specified
|
|
// variable in the specified locations, except those which are NULL.
|
|
// Variable number n must be in the range 1..MR_trace_var_count().
|
|
|
|
extern const char *MR_trace_return_var_info(int n, const char **name_ptr,
|
|
MR_TypeInfo *type_info_ptr, MR_Word *value_ptr);
|
|
|
|
// If the variable specified by n is a head variable, then store
|
|
// its argument position in *num and return NULL, otherwise return an error.
|
|
|
|
extern const char *MR_trace_headvar_num(int n, int *num);
|
|
|
|
// Print the call of the current level as a goal.
|
|
//
|
|
// The goal is printed to the given file if the file pointer is non-NULL.
|
|
// The goal is printed by giving it to the specified browser.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored.
|
|
|
|
extern const char *MR_trace_browse_one_goal(FILE *out,
|
|
MR_GoalBrowser browser, MR_BrowseCallerType caller,
|
|
MR_BrowseFormat format);
|
|
|
|
// Print I/O action <action_number> as a goal.
|
|
//
|
|
// The goal is printed to the given file if the file pointer is non-NULL.
|
|
// The goal is printed by giving it to the specified browser.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored.
|
|
|
|
extern const char *MR_trace_browse_action(FILE *out,
|
|
MR_IoActionNum action_number,
|
|
MR_GoalBrowser browser, MR_BrowseCallerType caller,
|
|
MR_BrowseFormat format);
|
|
|
|
// Parse the given word into a variable specification and the specification
|
|
// of a path within that variable. The variable is specified by either its name
|
|
// or its sequence number in the set of live variables at the current point;
|
|
// the desired part is specified by zero or more suffixes of the form
|
|
// ^argnum or /argnum.
|
|
|
|
extern const char *MR_trace_parse_var_path(char *word_spec,
|
|
MR_VarSpec *var_spec, char **path);
|
|
|
|
// Parse the given word into a variable specification and the specification
|
|
// of a path within that variable, as with MR_trace_parse_var_path, then
|
|
// look up and record the term at that path in *type_info and *value,
|
|
// and return NULL. If there is a problem with changing to a specified subterm,
|
|
// then return the term path of the problematic subterm and set *bad_subterm
|
|
// to true. If there is some other problem, return a description of the problem
|
|
// and set *bad_subterm to false.
|
|
|
|
extern const char *MR_trace_parse_lookup_var_path(char *word_spec,
|
|
MR_TypeInfo *type_info, MR_Word *value,
|
|
MR_bool *bad_subterm);
|
|
|
|
// Print the (names and) values of (the specified parts of) the specified
|
|
// variable. (The variable is specified by either its name or its sequence
|
|
// number in the set of live variables at the current point; the desired part
|
|
// is specified by zero or more suffixes of the form ^argnum or /argnum.
|
|
//
|
|
// The names are printed to the file specified by the out parameter if
|
|
// print_var_name is set, which requires out to be non-NULL.
|
|
// The values are printed by giving them to the specified browser.
|
|
// The last argument governs whether this function returns an error
|
|
// if the given variable specification is ambiguous.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored by the browser.
|
|
|
|
extern const char *MR_trace_parse_browse_one(FILE *out,
|
|
MR_bool print_var_name, char *word_spec,
|
|
MR_Browser browser, MR_BrowseCallerType caller,
|
|
MR_BrowseFormat format, MR_bool must_be_unique);
|
|
|
|
// Print the (name and) value of the specified variable.
|
|
// The name is printed to the given file if print_var_name is set.
|
|
// The values are printed by giving them to the specified browser.
|
|
// The last argument governs whether this function returns an error
|
|
// if the given variable specification is ambiguous.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored by the browser.
|
|
|
|
extern const char *MR_trace_browse_one(FILE *out, MR_bool print_var_name,
|
|
MR_VarSpec var_spec, MR_Browser browser,
|
|
MR_BrowseCallerType caller, MR_BrowseFormat format,
|
|
MR_bool must_be_unique);
|
|
|
|
extern const char *MR_trace_browse_one_path(FILE *out,
|
|
MR_bool print_var_name, MR_VarSpec var_spec,
|
|
char *path, MR_Browser browser,
|
|
MR_BrowseCallerType caller, MR_BrowseFormat format,
|
|
MR_bool must_be_unique);
|
|
|
|
// Print the list of the names and values of all variables live at the current
|
|
// point. The variables names are printed directly to the given file, but
|
|
// only if the given file pointer is not NULL; the variable values are
|
|
// printed by calling the given browser function on them.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored by the browser.
|
|
|
|
extern const char *MR_trace_browse_all(FILE *out, MR_Browser browser,
|
|
MR_BrowseFormat format);
|
|
|
|
// Sets the current set of variables to be ones live at the program point
|
|
// referred to by level_layout, base_sp and base_curfr arguments, and then
|
|
// prints them all.
|
|
//
|
|
// XXX Actually, the "out" parameter is currently ignored by the browser.
|
|
|
|
extern const char *MR_trace_browse_all_on_level(FILE *out,
|
|
const MR_LabelLayout *level_layout,
|
|
MR_Word *base_sp, MR_Word *base_curfr,
|
|
int ancestor_level, MR_bool print_optionals);
|
|
|
|
// If the given variable specification is unambiguous, then set *type_info
|
|
// to the type of the specified variable, set *value to its value, and set
|
|
// *name to its name (the storage name points to will remain valid only until
|
|
// the next call to MR_lookup_unambiguous_var_spec). Return a non-NULL error
|
|
// message if this is not possible.
|
|
|
|
extern const char *MR_lookup_unambiguous_var_spec(MR_VarSpec var_spec,
|
|
MR_TypeInfo *type_info, MR_Word *value,
|
|
const char **name);
|
|
|
|
// *value and type_info describe a term, and path specifies a subterm of that
|
|
// term. If the path is valid, return NULL and put the specified subterm in
|
|
// *sub_value and **sub_type_info. If it is not valid, return the invalid part
|
|
// of the path specification. This can be turned into an error message with
|
|
// MR_trace_bad_path.
|
|
|
|
extern char *MR_select_specified_subterm(char *path,
|
|
MR_TypeInfo type_info, MR_Word *value,
|
|
MR_TypeInfo *sub_type_info, MR_Word **sub_value);
|
|
|
|
// Given an invalid path specification, return an error message for that error.
|
|
//
|
|
// The returned string is valid only until the next call to MR_trace_bad_path
|
|
// or MR_trace_bad_path_in_var.
|
|
|
|
extern const char *MR_trace_bad_path(char *fullpath, char *badpath);
|
|
|
|
// Given a path specification that does not exist within the specified
|
|
// variable, return an error message for that error.
|
|
//
|
|
// The returned string is valid only until the next call to MR_trace_bad_path
|
|
// or MR_trace_bad_path_in_var.
|
|
|
|
extern const char *MR_trace_bad_path_in_var(MR_VarSpec *var_spec,
|
|
char *fullpath, char *badpath);
|
|
|
|
// Print the size of the specified variable(s) to the specified file.
|
|
// Return a non-NULL error message if this is not possible.
|
|
|
|
extern const char *MR_trace_print_size_one(FILE *out, char *word_spec);
|
|
|
|
// Print the size of all the variables at the current program point to the
|
|
// specified file. Return a non-NULL error message if this is not possible.
|
|
|
|
extern const char *MR_trace_print_size_all(FILE *out);
|
|
|
|
// Return the current goal as the components of a synthetic term.
|
|
|
|
extern void MR_convert_goal_to_synthetic_term(const char **functor_ptr,
|
|
MR_Word *arg_list_ptr, MR_bool *is_func_ptr);
|
|
|
|
// Return lists of names and univ values in the current environment.
|
|
|
|
extern void MR_trace_return_bindings(MR_Word *names_ptr,
|
|
MR_Word *values_ptr);
|
|
|
|
// A Readline completer for variable names.
|
|
|
|
extern MR_CompleterList *MR_trace_var_completer(const char *word,
|
|
size_t word_len);
|
|
|
|
#ifdef MR_TRACE_CHECK_INTEGRITY
|
|
|
|
// Checks whether any stack frame at the current program point contains
|
|
// references to terms with corrupted representations.
|
|
|
|
extern void MR_trace_check_integrity(const MR_LabelLayout *layout,
|
|
MR_TracePort port);
|
|
|
|
#endif // MR_TRACE_CHECK_INTEGRITY
|
|
|
|
#endif // MERCURY_TRACE_VARS_H
|