Files
mercury/tests/debugger/Mmakefile
Zoltan Somogyi fbfd4970df Make the debugging of minimal model tabling easier by providing a mechanism
Estimated hours taken: 32
Branches: main

Make the debugging of minimal model tabling easier by providing a mechanism
to print the contents of the nondet stack, *including* the values of the
variables in its stack frames, even for frames which are not ancestors
of the currently executing call.

runtime/mercury_stack_trace.[ch]:
	Add functions for traversing the nondet stack, and for keeping track of
	through which label control returns to each nondet stack frame, so that
	we know which label's layout structure to interpret the stack frame's
	contents. For some, this will be the return label of a call; for
	others, it will be the label of a resumption point stored in a
	redoip slot.

	Rename an old function to allow the new one to fit into our naming
	scheme.

runtime/mercury_stack_trace.[ch]:
runtime/mercury_tabling.c:
library/exception.m:
trace/mercury_trace.c:
	Add MR_ prefixes to the values of the enum returned by
	MR_stack_walk_step.

	Rename references to the renamed function.

runtime/mercury_conf_param.h:
	Add macros for debugging label names and for debugging retries (which
	needs label names, just as debugging tabling does).

	Add a macro for controlling whether mercury_debug.c prints raw
	addresses as well as offsets (for stack pointers) or label names (for
	labels). The raw pointers can be useful in debugging, but they need to
	be turned off in test cases one wants to be reproducible.

runtime/mercury_label.h:
runtime/mercury_conf_param.h:
	Move the MR_NEED_ENTRY_LABEL_ARRAY and MR_NEED_ENTRY_LABEL_INFO macros
	from mercury_label.h to mercury_conf_param.h, since mercury_debug.c
	also needs them now.

runtime/mercury_debug.c:
	addresses as well as offsets (for stack pointers) or label names (for
	labels). The raw pointers can be useful in debugging, but they need to
	be turned off in test cases one wants to be reproducible.

runtime/mercury_init.h:
runtime/mercury_wrapper.[ch]:
util/mkinit.c:
	Add a global variable pointing to a function through which the stack
	walk code in runtime/mercury_stack_trace.c can invoke code from the
	debugger to print the values of the variables in nondet stack frames
	without breaking the rule prohibiting references to the trace directory
	from the runtime directory.

runtime/mercury_wrapper.c:
	Define the succip of the dummy frame at the bottom of the nondet stack,
	to avoid dereferencing a garbage pointer during detailed stack dumps.

runtime/mercury_goto.h:
	Add a mechanism for always registering the name of a specific label,
	even if label names are not being registered in general. This mechanism
	is intended to be used for labels such as do_fail, which occur
	frequently in nondet stack traces.

runtime/mercury_context.c:
runtime/mercury_engine.c:
runtime/mercury_ho_call.c:
runtime/mercury_trace_base.c:
runtime/mercury_wrapper.c:
	Use this mechanism for the labels defined in these modules.

library/builtin.m:
	Define type_ctor_infos for the pseudotypes representing nondet stack
	frame slots unconditionally, since the debugger may now need them.

trace/mercury_trace.c:
	Add conditionally enabled to code to make debugging retry easier.

trace/mercury_trace_internal.c:
	Add a -d option to the nondet_stack command that causes it to print
	detailed nondet stack dumps, including the names and values of the
	variables in each nondet stack frame.

trace/mercury_trace_vars.c:
	Provide a mechanism for printing the variables of a stack frame
	even when that stack frame is not an ancestor of the current call.

doc/user_guide.texi:
	Document the new option of the nondet_stack command.

tests/debugger/nondet_stack.{m,inp,exp,exp2}:
	A new test case to test "nondet_stack -d".

tests/debugger/Mmakefile:
	Enable the new test case.
2001-12-04 00:44:41 +00:00

336 lines
11 KiB
Plaintext

#-----------------------------------------------------------------------------#
main_target: check
include ../Mmake.common
-include ../Mmake.params
#-----------------------------------------------------------------------------#
# We suppress the printing of the banner, because different workspaces
# may get different version numbers printed in it. This would otherwise be
# the source of irrelevant difference between the actual and expected outputs.
MDB = MERCURY_SUPPRESS_MDB_BANNER=yes mdb
#-----------------------------------------------------------------------------#
RETRY_PROGS = \
all_solutions \
browser_test \
mdb_command_test \
queens \
retry \
tabled_read
NONRETRY_PROGS = \
breakpoints \
browse_pretty \
debugger_regs \
exception_cmd \
exception_value \
exception_vars \
existential_type_classes \
field_names \
implied_instance \
interpreter \
loopcheck \
multi_parameter \
nondet_stack \
output_term_dep \
polymorphic_output \
resume_typeinfos \
shallow
# The following tests are disabled, since currently they get some spurious
# failures if readline support is enabled:
# interactive
# Note that some of the make rules for interactive are disabled too.
MCFLAGS-shallow = --trace shallow
MCFLAGS-tabled_read = --trace-table-io
MCFLAGS = --trace deep
MLFLAGS = --trace
C2INITFLAGS = --trace
# We need to use shared libraries for interactive queries to work.
# The following is necessary for shared libraries to work on Linux.
GRADEFLAGS-interactive = --pic-reg
MLFLAGS-interactive = --shared
# Debugging doesn't yet don't work in MLDS grades (hl*), and the retry command
# doesn't and will not work in deep profiling grades (profdeep).
# Also base grades `jump' and `fast' cannot be used with
# stack layouts (which are required for tracing).
ifneq "$(findstring hl,$(GRADE))" ""
PROGS=
else
ifneq "$(findstring profdeep,$(GRADE))" ""
# Eventually, this should be DEBUGGER_PROGS=$(NONRETRY_PROGS).
# However, the code that is required to switch off the profiling
# primitives in Mercury code invoked by the debugger (e.g. for
# browsing) has not yet been implemented.
DEBUGGER_PROGS=
else
DEBUGGER_PROGS=$(NONRETRY_PROGS) $(RETRY_PROGS)
endif
ifneq "$(findstring asm_,$(GRADE))" ""
PROGS=$(DEBUGGER_PROGS)
else
ifneq "$(findstring jump,$(GRADE))" ""
PROGS=
else
ifneq "$(findstring fast,$(GRADE))" ""
PROGS=
else
PROGS=$(DEBUGGER_PROGS)
endif
endif
endif
endif
#-----------------------------------------------------------------------------#
all_solutions.out: all_solutions all_solutions.inp
$(MDB) ./all_solutions < all_solutions.inp > all_solutions.out 2>&1
breakpoints.out: breakpoints breakpoints.inp
$(MDB) ./breakpoints < breakpoints.inp > breakpoints.out 2>&1
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
browse_pretty.out: browse_pretty browse_pretty.inp
$(MDB) ./browse_pretty < browse_pretty.inp 2>&1 | \
sed 's/io.m:[0-9]*/io.m:NNNN/g' > browse_pretty.out 2>&1
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
browser_test.out: browser_test browser_test.inp
$(MDB) ./browser_test < browser_test.inp 2>&1 | \
sed 's/io.m:[0-9]*/io.m:NNNN/g' > browser_test.out 2>&1
debugger_regs.out: debugger_regs debugger_regs.inp
$(MDB) ./debugger_regs < debugger_regs.inp > debugger_regs.out 2>&1
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
exception_value.out: exception_value exception_value.inp
$(MDB) ./exception_value < exception_value.inp 2>&1 | \
sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' | \
sed -e '/EXCP/s/).*/)/' > exception_value.out 2>&1
# The exception_cmd, exception_vars, polymorphic_output and loopcheck tests
# are supposed to return a non-zero exit status, since they exit by throwing
# an exception. We strip the goal paths from their exception events, since
# the exact goal paths are dependent on optimization level. The stripping
# must be done outside the condition of the if-then-else.
exception_cmd.out: exception_cmd exception_cmd.inp
if $(MDB) ./exception_cmd < exception_cmd.inp \
> exception_cmd.tmp 2>&1; \
then \
sed -e '/EXCP/s/).*/)/' < exception_cmd.tmp \
> exception_cmd.out 2>&1; \
rm exception_cmd.tmp; \
false; \
else \
sed -e '/EXCP/s/).*/)/' < exception_cmd.tmp \
> exception_cmd.out 2>&1; \
rm exception_cmd.tmp; \
true; \
fi
exception_vars.out: exception_vars exception_vars.inp
if $(MDB) ./exception_vars < exception_vars.inp \
> exception_vars.tmp 2>&1; \
then \
sed -e '/EXCP/s/).*/)/' < exception_vars.tmp \
> exception_vars.out 2>&1; \
rm exception_vars.tmp; \
false; \
else \
sed -e '/EXCP/s/).*/)/' < exception_vars.tmp \
> exception_vars.out 2>&1; \
rm exception_vars.tmp; \
true; \
fi
polymorphic_output.out: polymorphic_output polymorphic_output.inp
if $(MDB) ./polymorphic_output < polymorphic_output.inp \
> polymorphic_output.tmp 2>&1; \
then \
sed -e '/EXCP/s/).*/)/' < polymorphic_output.tmp\
> polymorphic_output.out 2>&1; \
rm polymorphic_output.tmp; \
false; \
else \
sed -e '/EXCP/s/).*/)/' < polymorphic_output.tmp\
> polymorphic_output.out 2>&1; \
rm polymorphic_output.tmp; \
true; \
fi
loopcheck.out: loopcheck loopcheck.inp
if $(MDB) ./loopcheck < loopcheck.inp \
> loopcheck.tmp 2>&1; \
then \
sed -e '/EXCP/s/).*/)/' < loopcheck.tmp \
> loopcheck.out 2>&1; \
rm loopcheck.tmp; \
false; \
else \
sed -e '/EXCP/s/).*/)/' < loopcheck.tmp \
> loopcheck.out 2>&1; \
rm loopcheck.tmp; \
true; \
fi
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
existential_type_classes.out: existential_type_classes \
existential_type_classes.inp
$(MDB) ./existential_type_classes < existential_type_classes.inp 2>&1 | \
sed 's/string.m:[0-9]*/string.m:NNNN/g' > existential_type_classes.out
field_names.out: field_names field_names.inp
$(MDB) ./field_names < field_names.inp > field_names.out 2>&1
implied_instance.out: implied_instance implied_instance.inp
$(MDB) ./implied_instance < implied_instance.inp \
> implied_instance.out 2>&1
interpreter.out: interpreter interpreter.inp
$(MDB) ./interpreter interpreter.m < interpreter.inp \
> interpreter.out 2>&1
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
multi_parameter.out: multi_parameter multi_parameter.inp
$(MDB) ./multi_parameter < multi_parameter.inp 2>&1 | \
sed 's/char.m:[0-9]*/char.m:NNNN/g' > multi_parameter.out
# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
output_term_dep.out: output_term_dep output_term_dep.inp
$(MDB) ./output_term_dep < output_term_dep.inp 2>&1 | \
sed 's/io.m:[0-9]*/io.m:NNNN/g' > output_term_dep.out 2>&1
queens.out: queens queens.inp
$(MDB) ./queens < queens.inp > queens.out 2>&1
nondet_stack.out: nondet_stack nondet_stack.inp
$(MDB) ./nondet_stack < nondet_stack.inp 2>&1 | \
sed 's/nondet_stack.m:[0-9]*/nondet_stack.m:NNNN/g' \
> nondet_stack.out 2>&1
resume_typeinfos.out: resume_typeinfos resume_typeinfos.inp
$(MDB) ./resume_typeinfos < resume_typeinfos.inp 2>&1 | \
sed 's/resume_typeinfos.m:[0-9]*/resume_typeinfos.m:NNNN/g' \
> resume_typeinfos.out 2>&1
retry.out: retry retry.inp
$(MDB) ./retry < retry.inp > retry.out 2>&1
shallow.out: shallow shallow.inp
$(MDB) ./shallow < shallow.inp > shallow.out 2>&1
tabled_read.out: tabled_read tabled_read.inp
$(MDB) ./tabled_read < tabled_read.inp > tabled_read.out 2>&1
# Note that interactive.out.orig depends on $(interactive.ints) because
# interactive.inp contains interactive queries that require interactive.ints
# to have been built.
# This rule is commented out while the interactive test case is disabled,
# because otherwise we get an undefined variable warning from make.
# interactive.out.orig: interactive interactive.inp $(interactive.ints)
# $(MDB) ./interactive < interactive.inp > interactive.out.orig 2>&1
# We pipe the output through sed to remove some spurious warnings that
# `ld' issues.
# XXX we should fix the spurious warnings about unresolved symbols.
# (The spurious warnings about exception handling are due to a flaw
# in the Digital Unix 3.2 linker, so that one is DEC's problem.)
interactive.out: interactive.out.orig
cat interactive.out.orig | \
sed \
-e '/\/usr\/bin\/ld:$$/N' \
-e 's/\/usr\/bin\/ld:.//' \
-e '/Warning: Linking some objects which contain exception information sections$$/N' \
-e 's/Warning: Linking some objects which contain exception information sections.//' \
-e '/ and some which do not. This may cause fatal runtime exception handling$$/N' \
-e 's/ and some which do not. This may cause fatal runtime exception handling.//' \
-e '/ problems (last obj encountered without exceptions was .*)\.$$/N' \
-e 's/ problems (last obj encountered without exceptions was .*)\..//' \
-e '/Warning: Unresolved:$$/N' \
-e 's/Warning: Unresolved:.//' \
-e '/<predicate .main.\/2 mode 0>$$/N' \
-e 's/<predicate .main.\/2 mode 0>.//' \
-e '/<predicate .interactive:qperm.\/2 mode 0>$$/N' \
-e 's/<predicate .interactive:qperm.\/2 mode 0>.//' \
-e '/__start$$/N' \
-e 's/__start.//' \
> interactive.out
# ignore egcs internal errors -- those are not our fault
if grep 'gcc.*Internal compiler error' interactive.out; then \
cp interactive.exp interactive.out; \
fi
# We ignore the result of this action because
# the exit status of grep is not useful in this case
mdb_command_test.out: mdb_command_test mdb_command_test.inp
-$(MDB) ./mdb_command_test < mdb_command_test.inp 2>&1 \
| egrep "internal error in the trace help system" \
> mdb_command_test.out
#-----------------------------------------------------------------------------#
DEPS= $(PROGS:%=$(deps_subdir)%.dep)
DEPENDS= $(PROGS:%=%.depend)
OUTS= $(PROGS:%=%.out)
RESS= $(PROGS:%=%.res)
dep_local: $(DEPS)
depend_local: $(DEPENDS)
check_local: $(OUTS) $(RESS)
all_local: $(PROGS)
#-----------------------------------------------------------------------------#
SUBDIRS = declarative
check_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) check) || exit 1; \
done
dep_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) dep) || exit 1; \
done
depend_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) depend) || exit 1; \
done
realclean_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) realclean) || exit 1; \
done
clean_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) clean) || exit 1; \
done
all_subdirs:
+for dir in $(SUBDIRS); do \
(cd $$dir && $(SUBDIR_MMAKE) all) || exit 1; \
done
#-----------------------------------------------------------------------------#