mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
The crash that this diff fixes occurred when giving a command such as
"print Var^1" to mdb, where the first argument of Var is a direct arg.
runtime/mercury_ml_expand_body.h:
When deconstructing a term with a direct arg, return NULL
as the value of expand_info->chosen_arg_word_sized_ptr.
The crash occurred when we returned a non-null pointer,
which violated the expectations of trace/mercury_trace_vars.c
and its callers. (Not surprising, since those that function and
its callers were written long before the direct_arg optimization
was added to the system.)
runtime/mercury_deconstruct.h:
Document the rationale behind the above changes. (The contents of
mercury_ml_expand_body.h are #included in mercury_deconstruct.c.)
trace/mercury_trace_vars.c:
Add the debugging code I used to track down this issue, in disabled form.
Fix missing copyright year.
trace/mercury_trace_browse.c:
Delete obsolete comment.
Fix missing copyright years.
tests/debugger/direct_arg_test.{m,inp,exp}:
A test case for this bug.
tests/debugger/Mmakefile:
Enable the new test case.
compiler/hlds_out_type_table.m:
When dumping out the data constructors in the type table,
if a constructor has names for some of its fields,
put the name and the type of each field on different lines.
In the original test case for this bug, of which direct_arg_test.m
is an extreme simplification, pretty much every line overflows
without this.
Also, factor out some duplicated code, and replace bools with values
of a bespoke type.
This directory holds the trace subsystem, i.e. the part of the Mercury debugger that is written in C code. Notes on interfacing with other subsystems ------------------------------------------ If tracing is enabled, the compiler includes calls to MR_trace() in the generated C code. The trace subsystem in this directory is therefore called directly from Mercury code, via MR_trace() in runtime/mercury_trace_base.c. One of the first things it does is to save the original values of the Mercury registers in a variable called `saved_regs'. The reason it needs to do this is that the code here may modify registers, e.g. by allocating memory using incr_hp or by calling Mercury code. Once the original values of the registers have been saved, the trace subsystem is free to modify the Mercury registers. So for all code in this directory, the usual convention is that the original values of the Mercury registers are in `saved_regs', while the current (scratch) values for the normal non-transient Mercury registers etc. are in their normal locations, not in the fake_reg copies, and the transient (register window) registers, if any, are in the fake_reg copies. Any code which uses macros such as incr_hp(), list_cons(), make_aligned_string(), etc. that modify the heap pointer must call restore_transient_regs() beforehand and must call save_transient_regs() afterwards. The simplest way to do this is to use the macro MR_TRACE_USE_HP() in trace/mercury_trace_util.h. The tracer may invoke Mercury code defined in the browser or library directories if that code is exported to C using `pragma export'. But any calls from functions here to code defined in Mercury and exported using `pragma export', i.e. functions starting with `ML_' prefixes, must be preceded by a call to save_registers() and followed by a call to restore_registers(). The simplest way to do this is to use the macro MR_TRACE_CALL_MERCURY() in trace/mercury_trace_util.h.