[m-rev.] for review: controlling retry across I/O
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Oct 30 18:03:01 AEDT 2002
For review by anyone, but Mark should definitely look at least at the part
of the diff marked by an XXX for him.
Zoltan.
Rationalize the mechanisms we use to control retry across I/O.
After this change, we never ask questions about retry across I/O if the retry
is guaranteed to be safe. If the I/O is not guaranteed to be safe, there are
three things we can do:
- We ask the user whether they really want to. This is the default, and can be
asked for explicitly with "retry --interactive".
- We perform the retry without asking questions. This can be asked for
explicitly with "retry --force".
- We abort the retry automatically without asking questions. This can be asked
for explicitly with "retry --only-if-safe".
The implicit retries used to implement declarative debugging and the indirect
retries needed in the presence of minimal model tabling use the last option.
We need two conditions for the retry to be guaranteed to be safe:
- All I/O actions must be tabled.
- The retry must be wholly within the tabled region of the execution.
The first is normally assured by a debugging grade. However, to allow test
cases to test the behavior of retries even with --only-if-safe (and hence to
allow the testing of declarative debugging), we have another new flag,
--assume-all-io-is-tabled, which asserts the first condition to be true
even in non-debugging grades. This option applies both to the retry command
and the dd and dd_dd commands.
doc/user_guide.texi:
Move the misc commands (which are intended for use by everybody)
before the experimental and developer commands (which are intended
for use only by developers).
Document the dd_dd command in the developer section.
Document the new options of the retry, dd and dd_dd commands, with
the documentation of the developer-only options commented out.
Consolidate the documentation of the two variants of the retry command
into one, in order to reduce duplication.
Add a cross-reference requested by Fergus.
Add an XXX asking Mark to document the optional argument of dd_dd.
doc/generate_mdb_doc:
Switch the order of sections to match the change in user_guide.texi.
doc/mdb_categories:
Switch the order of sections to match the change in user_guide.texi,
and include dd and dd_dd in the command lists.
runtime/mercury_trace_base.[ch]:
Add a pair of global variables recording the event numbers at which
I/O tabling is turned on and off.
Make some declarations use the right typedef.
trace/mercury_trace.[ch]:
Make MR_trace_retry respect the values of the new options
controlling retries passed to it.
Convert this file to four-space indentation to reduce the number of
line-wraps.
trace/mercury_trace_declarative.[ch]:
Record the value of one of the options controlling retries for the
current invocation of `dd' in a global variable, since the front end
can initiate retries even after the initial retry.
Pass the required option values to retry.
trace/mercury_trace_external.c:
Pass the required option values to retry.
trace/mercury_trace_internal.c:
Implement the new options of the retry, dd and dd_dd commands.
Pass the required option values to retry.
Make "table_io start" and "table_io stop" record the relevant event
numbers in the global variables designed to hold them, for use in
mercury_trace.c in deciding whether a retry is safe.
Make indirect retries (used only in minimal model grades) use only safe
retries.
Make the dd and dd_dd commands use the help system to print usage
messages, now that they are both documented.
To make this possible, make the dd command part of the "misc" category
and the dd_dd command part of the "developer" category, which are the
categories they are documented under in user_guide.texi.
tests/debugger/mdb_command_test.inp:
Update this automatically generated list of commands.
tests/debugger/tabled_read.{inp,exp}:
tests/debugger/tabled_read_decl.{inp,exp}:
Update the retry commands in these tests to use the new options
where relevant.
tests/debugger/declarative/tabled_read_decl.{inp,exp}:
Update the dd commands in these tests to use the new options
where relevant.
cvs diff: Diffing .
cvs diff: Diffing bench
cvs diff: Diffing bench/progs
cvs diff: Diffing bench/progs/compress
cvs diff: Diffing bench/progs/icfp2000
cvs diff: Diffing bench/progs/icfp2001
cvs diff: Diffing bench/progs/nuc
cvs diff: Diffing bench/progs/ray
cvs diff: Diffing bench/progs/tree234
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/generate_mdb_doc
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/generate_mdb_doc,v
retrieving revision 1.6
diff -u -b -r1.6 generate_mdb_doc
--- doc/generate_mdb_doc 22 Oct 2002 04:36:02 -0000 1.6
+++ doc/generate_mdb_doc 29 Oct 2002 10:04:36 -0000
@@ -16,7 +16,7 @@
debug_cmd_path="debug debugger"
for section in interactive forward backward browsing breakpoint \
- i/o parameter help exp developer misc
+ i/o parameter help misc exp developer
do
case $section in
interactive) category=queries ;;
Index: doc/mdb_categories
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/mdb_categories,v
retrieving revision 1.14
diff -u -b -r1.14 mdb_categories
--- doc/mdb_categories 22 Oct 2002 04:36:02 -0000 1.14
+++ doc/mdb_categories 29 Oct 2002 10:04:07 -0000
@@ -52,21 +52,22 @@
For help on the `help' command, type `help help help'.
end
-document_category 900 exp
+document_category 900 misc
+misc - Commands that are of interest to most users but do not fit into
+ other categories. The misc commands are `source', `save', `dd'
+ and `quit'.
+
+end
+document_category 1000 exp
exp - Commands that let users collect and inspect experimental
data about the behavior of the program. The exp commands are
`histogram_all', `histogram_exp', and `clear_histogram'.
end
-document_category 1000 developer
+document_category 1100 developer
developer - Commands that are intended to be of use only to developers
of the Mercury implementation. The developer commands are
`nondet_stack', `stack_regs', `all_regs', `proc_stats',
- `label_stats', `print_optionals' and `unhide_events'.
-
-end
-document_category 1100 misc
-misc - Commands that do not fit into other categories.
- The misc commands are `source', `save' and `quit'.
+ `label_stats', `print_optionals', `unhide_events' and `dd_dd'.
end
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.333
diff -u -b -r1.333 user_guide.texi
--- doc/user_guide.texi 26 Oct 2002 14:15:33 -0000 1.333
+++ doc/user_guide.texi 30 Oct 2002 03:47:22 -0000
@@ -1992,7 +1992,7 @@
(The mdb @samp{retry} command
restores the computation to a state it had earlier,
allowing the programmer to explore code that the program has already executed;
-see its documentation in the Debugger commands section below.)
+see its documentation in the @ref{Debugger commands} section below.)
In the absence of I/O tabling,
retries across I/O actions can have bad consequences.
Retry of a goal that reads some input requires that input to be provided twice;
@@ -2065,9 +2065,9 @@
* I/O tabling commands::
* Parameter commands::
* Help commands::
+* Miscellaneous commands::
* Experimental commands::
* Developer commands::
-* Miscellaneous commands::
@end menu
@node Interactive query commands
@@ -2331,13 +2331,19 @@
@sp 1
@table @code
- at item retry [-f]
+ at item retry [-fio] [@var{num}]
@kindex retry (mdb command)
-Restarts execution at the call port
+If the optional number is not given,
+restarts execution at the call port
of the call corresponding to the current event.
+If the optional number is given,
+restarts execution at the call port of the call corresponding to
+the @var{num}'th ancestor of the call to which the current event belongs.
+For example, if @var{num} is 1, it restarts the parent of the current call.
@sp 1
The command will report an error unless
-the values of all the input arguments are available at the current port.
+the values of all the input arguments of the selected call are available
+at the return site at which control would reenter the selected call.
(The compiler will keep the values
of the input arguments of traced predicates as long as possible,
but it cannot keep them beyond the point where they are destructively updated.)
@@ -2345,10 +2351,17 @@
the debugger can perform a retry if the only missing value is of
type `io__state' (there can be only one io__state at any given time).
@sp 1
-Since retries over I/O actions are not always safe,
+Retries over I/O actions are guaranteed to be safe
+only if the events at which the retry starts and ends
+are both within the I/O tabled region of the program's execution.
+If the retry is not guaranteed to be safe,
the debugger will normally ask the user if they really want to do this.
The option @samp{-f} or @samp{--force} suppresses the question,
-and tells the debugger that retrying over I/O is OK.
+telling the debugger that retrying over I/O is OK;
+the option @samp{-o} or @samp{--only-if-safe} suppresses the question,
+telling the debugger that retrying over I/O is not OK;
+the option @samp{-i} or @samp{--interactive} restores the question
+if a previous option suppressed it.
@c @sp 1
@c A retry in which the values of all input arguments are available
@c works fine, provided that the predicates defined in C code that are
@@ -2382,26 +2395,6 @@
@c This may require a noticeable amount of time.
@c XXX not yet
@c and may result in the execution of I/O and/or other side-effects.
- at sp 1
- at item retry [-f] @var{num}
-Restarts execution at the call port of the call corresponding to
-the @var{num}'th ancestor of the call to which the current event belongs.
-For example, if @var{num} is 1, it restarts the parent of the current call.
- at sp 1
-The command will report an error unless
-the values of all the input arguments of the selected call are available
-at the return site at which control would reenter the selected call.
-(The compiler will keep the values
-of the input arguments of traced predicates as long as possible,
-but it cannot keep them beyond the point where they are destructively updated.)
-The exception is values of type `io__state';
-the debugger can perform a retry if the only missing value is of
-type `io__state' (there can be only one io__state at any given time).
- at sp 1
-Since retries over I/O actions are not always safe,
-the debugger will normally ask the user if they really want to do this.
-The option @samp{-f} or @samp{--force} suppresses the question,
-and tells the debugger that retrying over I/O is OK.
@end table
@sp 1
@@ -3104,6 +3097,44 @@
@end table
@sp 1
+ at node Miscellaneous commands
+ at subsection Miscellaneous commands
+
+ at sp 1
+ at table @code
+ at item source [-i] @var{filename}
+ at kindex source (mdb command)
+Executes the commands in the file named @var{filename}.
+ at sp 1
+The option @samp{-i} or @samp{--ignore-errors} tells @samp{mdb}
+not to complain if the named file does not exist or is not readable.
+ at sp 1
+ at item save @var{filename}
+ at kindex save (mdb command)
+Saves current set of breakpoints and the current set of aliases
+in the named file as a set of @samp{break} and @samp{alias} commands.
+Sourcing the file will recreate the current breakpoints and aliases.
+ at sp 1
+ at item dd
+ at c @item dd [--assume-all-io-is-tabled]
+ at c The --assume-all-io-is-tabled option is for developers only. Specifying it
+ at c makes an assertion, and if the assertion is incorrect, the resulting
+ at c behavior would be hard for non-developers to understand. The option is
+ at c therefore deliberately not documented.
+Starts declarative debugging
+using the current event as the initial symptom.
+For details, see @ref{Declarative debugging}.
+ at sp 1
+ at item quit [-y]
+ at kindex quit (mdb command)
+Quits the debugger and aborts the execution of the program.
+If the option @samp{-y} is not present, asks for confirmation first.
+Any answer starting with @samp{y}, or end-of-file, is considered confirmation.
+ at sp 1
+End-of-file on the debugger's input is considered a quit command.
+ at end table
+
+ at sp 1
@node Developer commands
@subsection Developer commands
@@ -3166,39 +3197,20 @@
@sp 1
@item unhide_events off
Tells the debugger to hide events that are normally hidden.
- at end table
-
- at sp 1
- at node Miscellaneous commands
- at subsection Miscellaneous commands
-
- at sp 1
- at table @code
- at item source [-i] @var{filename}
- at kindex source (mdb command)
-Executes the commands in the file named @var{filename}.
- at sp 1
-The option @samp{-i} or @samp{--ignore-errors} tells @samp{mdb}
-not to complain if the named file does not exist or is not readable.
@sp 1
- at item save @var{filename}
- at kindex save (mdb command)
-Saves current set of breakpoints and the current set of aliases
-in the named file as a set of @samp{break} and @samp{alias} commands.
-Sourcing the file will recreate the current breakpoints and aliases.
- at sp 1
- at item quit [-y]
- at kindex quit (mdb command)
-Quits the debugger and aborts the execution of the program.
-If the option @samp{-y} is not present, asks for confirmation first.
-Any answer starting with @samp{y}, or end-of-file, is considered confirmation.
- at sp 1
-End-of-file on the debugger's input is considered a quit command.
- at sp 1
- at item dd
-Starts declarative debugging,
-using the current event as the initial symptom.
-For details, see @ref{Declarative debugging}.
+ at item dd_dd
+ at c @item dd_dd [filename]
+ at c XXX Mark, please document the optional argument of dd_dd
+ at c @item dd_dd [--assume-all-io-is-tabled] [filename]
+ at c The --assume-all-io-is-tabled option is for developers only. Specifying it
+ at c makes an assertion, and if the assertion is incorrect, the resulting
+ at c behavior would be hard for non-developers to understand. The option is
+ at c therefore deliberately not documented.
+Starts declarative debugging
+using the current event as the initial symptom,
+but unlike the standard @samp{dd} command,
+does not turn off the events generated by the declarative debugger itself.
+This makes it possible to debug the declarative debugger itself.
@end table
@node Declarative debugging
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.48
diff -u -b -r1.48 mercury_trace_base.c
--- runtime/mercury_trace_base.c 22 Oct 2002 04:36:10 -0000 1.48
+++ runtime/mercury_trace_base.c 27 Oct 2002 22:34:06 -0000
@@ -59,10 +59,12 @@
MR_IoTablingPhase MR_io_tabling_phase = MR_IO_TABLING_UNINIT;
MR_bool MR_io_tabling_enabled = MR_FALSE;
MR_TableNode MR_io_tabling_pointer = { 0 };
-MR_Unsigned MR_io_tabling_counter = 0;
-MR_Unsigned MR_io_tabling_counter_hwm = 0;
-MR_Unsigned MR_io_tabling_start = 0;
-MR_Unsigned MR_io_tabling_end = 0;
+MR_IoActionNum MR_io_tabling_counter = 0;
+MR_IoActionNum MR_io_tabling_counter_hwm = 0;
+MR_IoActionNum MR_io_tabling_start = 0;
+MR_IoActionNum MR_io_tabling_end = 0;
+MR_Unsigned MR_io_tabling_start_event_num = 0;
+MR_Unsigned MR_io_tabling_stop_event_num = 0;
MR_bool MR_io_tabling_debug = MR_FALSE;
#ifdef MR_REQUIRE_TRACING
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_trace_base.h
--- runtime/mercury_trace_base.h 22 Oct 2002 04:36:10 -0000 1.29
+++ runtime/mercury_trace_base.h 27 Oct 2002 22:33:19 -0000
@@ -272,6 +272,12 @@
/* The highest I/O action number which is to be tabled. */
extern MR_IoActionNum MR_io_tabling_end;
+/* The event number at which I/O tabling was started; zero before start. */
+extern MR_Unsigned MR_io_tabling_start_event_num;
+
+/* The event number at which I/O tabling was stopped; zero before stop. */
+extern MR_Unsigned MR_io_tabling_stop_event_num;
+
/* The flag that controls whether we should generate diagnostics. */
extern MR_bool MR_io_tabling_debug;
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.20
diff -u -b -r1.20 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp 22 Oct 2002 04:36:14 -0000 1.20
+++ tests/debugger/mdb_command_test.inp 30 Oct 2002 05:04:46 -0000
@@ -38,6 +38,10 @@
context xyzzy xyzzy xyzzy xyzzy xyzzy
scope xyzzy xyzzy xyzzy xyzzy xyzzy
unalias xyzzy xyzzy xyzzy xyzzy xyzzy
+source xyzzy xyzzy xyzzy xyzzy xyzzy
+save xyzzy xyzzy xyzzy xyzzy xyzzy
+dd xyzzy xyzzy xyzzy xyzzy xyzzy
+quit xyzzy xyzzy xyzzy xyzzy xyzzy
histogram_all xyzzy xyzzy xyzzy xyzzy xyzzy
histogram_exp xyzzy xyzzy xyzzy xyzzy xyzzy
clear_histogram xyzzy xyzzy xyzzy xyzzy xyzzy
@@ -48,7 +52,4 @@
label_stats xyzzy xyzzy xyzzy xyzzy xyzzy
print_optionals xyzzy xyzzy xyzzy xyzzy xyzzy
unhide_events xyzzy xyzzy xyzzy xyzzy xyzzy
-source xyzzy xyzzy xyzzy xyzzy xyzzy
-save xyzzy xyzzy xyzzy xyzzy xyzzy
-quit xyzzy xyzzy xyzzy xyzzy xyzzy
-dd xyzzy xyzzy xyzzy xyzzy xyzzy
+dd_dd xyzzy xyzzy xyzzy xyzzy xyzzy
Index: tests/debugger/tabled_read.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.exp,v
retrieving revision 1.5
diff -u -b -r1.5 tabled_read.exp
--- tests/debugger/tabled_read.exp 22 Oct 2002 04:36:15 -0000 1.5
+++ tests/debugger/tabled_read.exp 30 Oct 2002 05:07:54 -0000
@@ -20,9 +20,7 @@
SoFar (arg 2) 0
N (arg 3) 123
DCG_2 (arg 5) state('<<c_pointer>>')
-mdb> retry
-Retry across I/O operations is not always safe.
-Are you sure you want to do it? y
+mdb> retry -o -a
E2: C2 3 CALL pred tabled_read:test/5-0 (det)
mdb> print *
Stream (arg 1) '<<c_pointer>>'
@@ -48,9 +46,7 @@
SoFar (arg 2) 0
N (arg 3) 789
DCG_2 (arg 5) state('<<c_pointer>>')
-mdb> retry
-Retry across I/O operations is not always safe.
-Are you sure you want to do it? y
+mdb> retry -f
E4: C3 3 CALL pred tabled_read:test/5-0 (det)
mdb> finish -n
E6: C3 3 EXIT pred tabled_read:test/5-0 (det)
Index: tests/debugger/tabled_read.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.inp,v
retrieving revision 1.2
diff -u -b -r1.2 tabled_read.inp
--- tests/debugger/tabled_read.inp 22 Oct 2002 04:36:15 -0000 1.2
+++ tests/debugger/tabled_read.inp 29 Oct 2002 22:11:13 -0000
@@ -8,8 +8,7 @@
continue
finish -n
print *
-retry
-y
+retry -o -a
print *
finish -n
print *
@@ -17,8 +16,7 @@
continue
finish -n
print *
-retry
-y
+retry -f
finish -n
print *
continue -S
Index: tests/debugger/tabled_read_decl.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read_decl.exp,v
retrieving revision 1.5
diff -u -b -r1.5 tabled_read_decl.exp
--- tests/debugger/tabled_read_decl.exp 22 Oct 2002 04:36:15 -0000 1.5
+++ tests/debugger/tabled_read_decl.exp 30 Oct 2002 05:08:04 -0000
@@ -20,9 +20,7 @@
SoFar (arg 2) 0
N (arg 3) 123
DCG_2 (arg 5) state('<<c_pointer>>')
-mdb> retry
-Retry across I/O operations is not always safe.
-Are you sure you want to do it? y
+mdb> retry -o -a
E2: C2 3 CALL pred tabled_read_decl:test/5-0 (det)
mdb> print *
Stream (arg 1) '<<c_pointer>>'
@@ -48,9 +46,7 @@
SoFar (arg 3) 0
N (arg 4) 456
DCG_2 (arg 6) state('<<c_pointer>>')
-mdb> retry
-Retry across I/O operations is not always safe.
-Are you sure you want to do it? y
+mdb> retry -o -a
E4: C3 3 CALL pred tabled_read_decl:poly_test/6-0 (det)
mdb> finish -n
E5: C3 3 EXIT pred tabled_read_decl:poly_test/6-0 (det)
Index: tests/debugger/tabled_read_decl.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read_decl.inp,v
retrieving revision 1.2
diff -u -b -r1.2 tabled_read_decl.inp
--- tests/debugger/tabled_read_decl.inp 22 Oct 2002 04:36:16 -0000 1.2
+++ tests/debugger/tabled_read_decl.inp 29 Oct 2002 22:12:05 -0000
@@ -8,8 +8,7 @@
continue
finish -n
print *
-retry
-y
+retry -o -a
print *
finish -n
print *
@@ -17,8 +16,7 @@
continue
finish -n
print *
-retry
-y
+retry -o -a
finish -n
print *
delete *
cvs diff: Diffing tests/debugger/declarative
Index: tests/debugger/declarative/tabled_read_decl.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/tabled_read_decl.exp,v
retrieving revision 1.4
diff -u -b -r1.4 tabled_read_decl.exp
--- tests/debugger/declarative/tabled_read_decl.exp 22 Oct 2002 04:36:23 -0000 1.4
+++ tests/debugger/declarative/tabled_read_decl.exp 30 Oct 2002 05:10:35 -0000
@@ -15,7 +15,7 @@
32: 4 3 EXIT pred tabled_read_decl:test/4-0 (det)
mdb> print
test('<<c_pointer>>', 1123, _, state('<<c_pointer>>'))
-mdb> dd
+mdb> dd -a
test('<<c_pointer>>', 1123, _, state('<<c_pointer>>'))
4 io actions:
read_char_code('<<c_pointer>>', 49)
Index: tests/debugger/declarative/tabled_read_decl.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/tabled_read_decl.inp,v
retrieving revision 1.2
diff -u -b -r1.2 tabled_read_decl.inp
--- tests/debugger/declarative/tabled_read_decl.inp 22 Oct 2002 04:36:24 -0000 1.2
+++ tests/debugger/declarative/tabled_read_decl.inp 29 Oct 2002 22:12:34 -0000
@@ -7,7 +7,7 @@
continue
finish -n
print
-dd
+dd -a
no
yes
yes
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/typeclasses
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.57
diff -u -b -r1.57 mercury_trace.c
--- trace/mercury_trace.c 24 Oct 2002 16:30:37 -0000 1.57
+++ trace/mercury_trace.c 29 Oct 2002 22:10:44 -0000
@@ -1,4 +1,7 @@
/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
** Copyright (C) 1997-2002 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
@@ -63,43 +66,40 @@
};
MR_Code *MR_trace_real(const MR_Label_Layout *layout);
-static MR_Code *MR_trace_event(MR_Trace_Cmd_Info *cmd,
- MR_bool interactive,
- const MR_Label_Layout *layout,
- MR_Trace_Port port, MR_Unsigned seqno,
- MR_Unsigned depth);
+static MR_Code *MR_trace_event(MR_Trace_Cmd_Info *cmd, MR_bool interactive,
+ const MR_Label_Layout *layout, MR_Trace_Port port,
+ MR_Unsigned seqno, MR_Unsigned depth);
static MR_bool MR_in_traced_region(const MR_Proc_Layout *proc_layout,
MR_Word *base_sp, MR_Word *base_curfr);
static MR_bool MR_is_io_state(MR_PseudoTypeInfo pti);
-static MR_bool MR_find_saved_io_counter(
- const MR_Label_Layout *call_label,
+static MR_bool MR_find_saved_io_counter(const MR_Label_Layout *call_label,
MR_Word *base_sp, MR_Word *base_curfr,
MR_Unsigned *saved_io_counter_ptr);
-static const MR_Label_Layout *MR_unwind_stacks_for_retry(
- const MR_Label_Layout *top_layout,
- int ancestor_level, MR_Word **base_sp_ptr,
- MR_Word **base_curfr_ptr,
- MR_Word **base_maxfr_ptr,
+static MR_bool MR_retry_within_io_tabled_region(MR_bool all_actions_tabled,
+ MR_Unsigned retry_event_num, MR_Unsigned cur_event_num);
+static const MR_Label_Layout
+ *MR_unwind_stacks_for_retry(const MR_Label_Layout
+ *top_layout, int ancestor_level, MR_Word **base_sp_ptr,
+ MR_Word **base_curfr_ptr, MR_Word **base_maxfr_ptr,
const char **problem);
static const char *MR_undo_updates_of_maxfr(const MR_Proc_Layout
- *level_layout, MR_Word *base_sp,
- MR_Word *base_curfr, MR_Word **maxfr_ptr);
-static MR_Word MR_trace_find_input_arg(
- const MR_Label_Layout *label,
- MR_Word *saved_regs,
- MR_Word *base_sp, MR_Word *base_curfr,
- MR_uint_least16_t var_num, MR_bool *succeeded);
+ *level_layout, MR_Word *base_sp, MR_Word *base_curfr,
+ MR_Word **maxfr_ptr);
+static MR_Word MR_trace_find_input_arg(const MR_Label_Layout *label,
+ MR_Word *saved_regs, MR_Word *base_sp,
+ MR_Word *base_curfr, MR_uint_least16_t var_num,
+ MR_bool *succeeded);
#ifdef MR_USE_MINIMAL_MODEL
-static MR_Retry_Result MR_check_minimal_model_calls(MR_Event_Info *event_info,
+static MR_Retry_Result
+ MR_check_minimal_model_calls(MR_Event_Info *event_info,
int ancestor_level, MR_Word *target_maxfr,
const char **problem);
#endif
static void MR_init_call_table_array(void);
-static void MR_maybe_record_call_table(
- const MR_Proc_Layout *level_layout,
- MR_Word *base_sp, MR_Word *base_curfr);
+static void MR_maybe_record_call_table(const MR_Proc_Layout
+ *level_layout, MR_Word *base_sp, MR_Word *base_curfr);
static void MR_reset_call_table_array(void);
static void MR_abandon_call_table_array(void);
@@ -159,8 +159,8 @@
** deep within interface traced code.
*/
- MR_ensure_big_enough2(depth, MR_trace_histogram, _all, _exp,
- int, INIT_HISTOGRAM);
+ MR_ensure_big_enough2(depth, MR_trace_histogram, _all, _exp, int,
+ INIT_HISTOGRAM);
if (depth > MR_trace_histogram_hwm) {
MR_trace_histogram_hwm = depth;
@@ -183,34 +183,26 @@
int lineno = 0;
max_r_num = layout->MR_sll_entry->MR_sle_max_r_num;
- if (max_r_num + MR_NUM_SPECIAL_REG >
- MR_MAX_SPECIAL_REG_MR)
- {
- event_info.MR_max_mr_num =
- max_r_num + MR_NUM_SPECIAL_REG;
+ if (max_r_num + MR_NUM_SPECIAL_REG > MR_MAX_SPECIAL_REG_MR) {
+ event_info.MR_max_mr_num = max_r_num + MR_NUM_SPECIAL_REG;
} else {
- event_info.MR_max_mr_num =
- MR_MAX_SPECIAL_REG_MR;
+ event_info.MR_max_mr_num = MR_MAX_SPECIAL_REG_MR;
}
port = (MR_Trace_Port) layout->MR_sll_port;
path = MR_label_goal_path(layout);
- MR_copy_regs_to_saved_regs(event_info.MR_max_mr_num,
- saved_regs);
- MR_trace_init_point_vars(layout, saved_regs, port,
- MR_FALSE);
+ MR_copy_regs_to_saved_regs(event_info.MR_max_mr_num, saved_regs);
+ MR_trace_init_point_vars(layout, saved_regs, port, MR_FALSE);
lineno = MR_get_line_number(saved_regs, layout, port);
- MR_COLLECT_filter(MR_trace_ctrl.MR_filter_ptr, seqno,
- depth, port, layout, path, lineno,
- &stop_collecting);
- MR_copy_saved_regs_to_regs(event_info.MR_max_mr_num,
- saved_regs);
+ MR_COLLECT_filter(MR_trace_ctrl.MR_filter_ptr, seqno, depth, port,
+ layout, path, lineno, &stop_collecting);
+ MR_copy_saved_regs_to_regs(event_info.MR_max_mr_num, saved_regs);
if (stop_collecting) {
MR_trace_ctrl.MR_trace_cmd = MR_CMD_GOTO;
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
}
#else
MR_fatal_error("attempt to use external debugger");
@@ -220,12 +212,10 @@
}
case MR_CMD_GOTO:
- if (MR_trace_event_number >=
- MR_trace_ctrl.MR_trace_stop_event)
- {
+ if (MR_trace_event_number >= MR_trace_ctrl.MR_trace_stop_event) {
port = (MR_Trace_Port) layout->MR_sll_port;
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -235,8 +225,7 @@
goto check_stop_print;
} else {
port = (MR_Trace_Port) layout->MR_sll_port;
- return MR_trace_event(&MR_trace_ctrl,
- MR_TRUE, layout, port,
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
seqno, depth);
}
@@ -249,9 +238,8 @@
if (! MR_port_is_final(port)) {
goto check_stop_print;
} else {
- return MR_trace_event(&MR_trace_ctrl,
- MR_TRUE, layout, port,
- seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout,
+ port, seqno, depth);
}
}
@@ -261,12 +249,9 @@
} else {
port = (MR_Trace_Port) layout->MR_sll_port;
- if (port == MR_PORT_FAIL ||
- port == MR_PORT_EXCEPTION)
- {
- return MR_trace_event(&MR_trace_ctrl,
- MR_TRUE, layout, port,
- seqno, depth);
+ if (port == MR_PORT_FAIL || port == MR_PORT_EXCEPTION) {
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout,
+ port, seqno, depth);
} else {
goto check_stop_print;
}
@@ -278,8 +263,8 @@
port != MR_PORT_FAIL &&
port != MR_PORT_EXCEPTION)
{
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -287,8 +272,8 @@
case MR_CMD_EXCP:
port = (MR_Trace_Port) layout->MR_sll_port;
if (port == MR_PORT_EXCEPTION) {
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -296,8 +281,8 @@
case MR_CMD_RETURN:
port = (MR_Trace_Port) layout->MR_sll_port;
if (port != MR_PORT_EXIT) {
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -305,8 +290,8 @@
case MR_CMD_MIN_DEPTH:
if (MR_trace_ctrl.MR_trace_stop_depth <= depth) {
port = (MR_Trace_Port) layout->MR_sll_port;
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -314,8 +299,8 @@
case MR_CMD_MAX_DEPTH:
if (MR_trace_ctrl.MR_trace_stop_depth >= depth) {
port = (MR_Trace_Port) layout->MR_sll_port;
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
} else {
goto check_stop_print;
}
@@ -345,24 +330,20 @@
port = (MR_Trace_Port) layout->MR_sll_port;
match = MR_event_matches_spy_point(layout, port, &action);
if (! match) {
- if (MR_trace_ctrl.MR_trace_print_level ==
- MR_PRINT_LEVEL_ALL)
- {
- return MR_trace_event(&MR_trace_ctrl, MR_FALSE,
- layout, port, seqno, depth);
+ if (MR_trace_ctrl.MR_trace_print_level == MR_PRINT_LEVEL_ALL) {
+ return MR_trace_event(&MR_trace_ctrl, MR_FALSE, layout, port,
+ seqno, depth);
}
return NULL;
}
- if ((! MR_trace_ctrl.MR_trace_strict) && action == MR_SPY_STOP)
- {
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE,
- layout, port, seqno, depth);
+ if ((! MR_trace_ctrl.MR_trace_strict) && action == MR_SPY_STOP) {
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+ seqno, depth);
}
- if (MR_trace_ctrl.MR_trace_print_level != MR_PRINT_LEVEL_NONE)
- {
+ if (MR_trace_ctrl.MR_trace_print_level != MR_PRINT_LEVEL_NONE) {
/*
** It doesn't matter whether action is MR_SPY_STOP or
** MR_SPY_PRINT; even if it is MR_SPY_STOP, we want
@@ -370,8 +351,8 @@
** stop.
*/
- return MR_trace_event(&MR_trace_ctrl, MR_FALSE,
- layout, port, seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_FALSE, layout, port,
+ seqno, depth);
}
}
@@ -416,8 +397,7 @@
MR_trace_event_number++;
- return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
- seqno, depth);
+ return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port, seqno, depth);
}
void
@@ -468,8 +448,7 @@
jumpaddr = MR_trace_event_external(cmd, &event_info);
} else {
- jumpaddr = MR_trace_event_internal(cmd, interactive,
- &event_info);
+ jumpaddr = MR_trace_event_internal(cmd, interactive, &event_info);
}
#else
/*
@@ -505,8 +484,9 @@
MR_Retry_Result
MR_trace_retry(MR_Event_Info *event_info, MR_Event_Details *event_details,
- int ancestor_level, MR_bool force_retry,
- const char **problem, FILE *in_fp, FILE *out_fp, MR_Code **jumpaddr)
+ int ancestor_level, MR_Retry_Across_Io across_io,
+ MR_bool assume_all_io_is_tabled, const char **problem,
+ FILE *in_fp, FILE *out_fp, MR_Code **jumpaddr)
{
MR_Word *base_sp;
MR_Word *base_curfr;
@@ -548,8 +528,7 @@
base_curfr = MR_saved_curfr(saved_regs);
base_maxfr = MR_saved_maxfr(saved_regs);
return_label_layout = MR_unwind_stacks_for_retry(top_layout,
- ancestor_level, &base_sp, &base_curfr, &base_maxfr,
- problem);
+ ancestor_level, &base_sp, &base_curfr, &base_maxfr, problem);
#ifdef MR_DEBUG_RETRY
MR_print_stack_regs(stdout, saved_regs);
#endif
@@ -597,9 +576,8 @@
saved_io_action_counter = 0;
for (i = 0; i < MR_all_desc_var_count(call_label); i++) {
- arg_value = MR_trace_find_input_arg(return_label_layout,
- saved_regs, base_sp, base_curfr,
- call_label->MR_sll_var_nums[i],
+ arg_value = MR_trace_find_input_arg(return_label_layout, saved_regs,
+ base_sp, base_curfr, call_label->MR_sll_var_nums[i],
&succeeded);
if (! succeeded) {
@@ -611,14 +589,11 @@
*/
has_io_state = MR_TRUE;
- found_io_action_counter =
- MR_find_saved_io_counter(call_label,
- base_sp, base_curfr,
- &saved_io_action_counter);
+ found_io_action_counter = MR_find_saved_io_counter(call_label,
+ base_sp, base_curfr, &saved_io_action_counter);
} else {
*problem = "Cannot perform retry because the "
- "values of some input arguments "
- "are missing.";
+ "values of some input arguments are missing.";
goto report_problem;
}
}
@@ -632,37 +607,57 @@
}
if (arg_num > 0) {
- MR_ensure_big_enough(arg_num, arg, MR_Word,
- MR_INIT_ARG_COUNT);
+ MR_ensure_big_enough(arg_num, arg, MR_Word, MR_INIT_ARG_COUNT);
args[arg_num] = arg_value;
} else {
MR_fatal_error("illegal location for input argument");
}
}
- if (has_io_state && !force_retry) {
- if (in_fp != NULL && out_fp != NULL) {
+ if (has_io_state) {
+ MR_Unsigned cur_event_num;
+ MR_Unsigned retry_event_num;
+ MR_bool all_actions_tabled;
+
+ cur_event_num = event_info->MR_event_number;
+
+ /*
+ ** Event numbers are stored *before* being incremented at calls.
+ */
+
+ if (MR_DETISM_DET_STACK(level_layout->MR_sle_detism)) {
+ retry_event_num = MR_event_num_stackvar(base_sp) + 1;
+ } else {
+ retry_event_num = MR_event_num_framevar(base_curfr) + 1;
+ }
+
+#ifdef MR_REQUIRE_TRACING
+ all_actions_tabled = MR_TRUE;
+#else
+ all_actions_tabled = assume_all_io_is_tabled;
+#endif
+
+ if (! MR_retry_within_io_tabled_region(all_actions_tabled,
+ retry_event_num, cur_event_num))
+ {
MR_bool allow_retry;
char *answer;
- if (found_io_action_counter
- || MR_io_tabling_counter == 0)
- {
- fprintf(out_fp,
- "Retry across I/O operations "
- "is not always safe.\n");
- answer = MR_trace_getline(
- "Are you sure you want to do it? ",
- in_fp, out_fp);
- } else {
+ switch (across_io) {
+
+ case MR_RETRY_IO_FORCE:
+ /* no further checks required */
+ break;
+
+ case MR_RETRY_IO_INTERACTIVE:
+ if (in_fp == NULL || out_fp == NULL) {
+ MR_fatal_error("MR_RETRY_IO_INTERACTIVE but null fp");
+ }
+
fprintf(out_fp,
- "Retry across I/O operations "
- "without saved I/O action numbers "
- "is not safe.\n");
+ "Retry across I/O operations is not always safe.\n");
answer = MR_trace_getline(
- "Are you sure you want to do it? ",
- in_fp, out_fp);
- }
+ "Are you sure you want to do it? ", in_fp, out_fp);
allow_retry = (answer[0] == 'y' || answer[0] == 'Y');
MR_free(answer);
@@ -670,9 +665,22 @@
*problem = "Retry aborted.";
goto report_problem;
}
+
+ break;
+
+ case MR_RETRY_IO_ONLY_IF_SAFE:
+ if (! all_actions_tabled) {
+ *problem = "Cannot perform retry: "
+ "not all I/O actions are tabled";
} else {
- *problem = "Cannot perform retry across I/O.";
+ *problem = "Cannot perform retry: "
+ "outside the safe region";
+ }
goto report_problem;
+
+ default:
+ MR_fatal_error("MR_trace_retry: unknown across_io");
+ }
}
}
@@ -740,8 +748,7 @@
MR_Word *this_frame;
location = level_layout->MR_sle_succip_locn;
- if (MR_LONG_LVAL_TYPE(location) != MR_LONG_LVAL_TYPE_STACKVAR)
- {
+ if (MR_LONG_LVAL_TYPE(location) != MR_LONG_LVAL_TYPE_STACKVAR) {
MR_fatal_error("illegal location for stored succip");
}
@@ -750,8 +757,7 @@
MR_print_succip_reg(stdout, saved_regs);
MR_print_stack_regs(stdout, saved_regs);
#endif
- MR_saved_succip(saved_regs) = (MR_Word *)
- MR_based_stackvar(this_frame,
+ MR_saved_succip(saved_regs) = (MR_Word *) MR_based_stackvar(this_frame,
MR_LONG_LVAL_NUMBER(location));
MR_saved_sp(saved_regs) -= level_layout->MR_sle_stack_slots;
#ifdef MR_DEBUG_RETRY
@@ -898,8 +904,7 @@
static MR_bool
MR_find_saved_io_counter(const MR_Label_Layout *call_label,
- MR_Word *base_sp, MR_Word *base_curfr,
- MR_Unsigned *saved_io_counter_ptr)
+ MR_Word *base_sp, MR_Word *base_curfr, MR_Unsigned *saved_io_counter_ptr)
{
const MR_Proc_Layout *level_layout;
MR_Unsigned saved_io_counter;
@@ -924,6 +929,35 @@
return MR_TRUE;
}
+static MR_bool
+MR_retry_within_io_tabled_region(MR_bool all_actions_tabled,
+ MR_Unsigned retry_event_num, MR_Unsigned cur_event_num)
+{
+ if (!all_actions_tabled) {
+ /* regardless of event numbers, some I/O actions may not be tabled */
+ return MR_FALSE;
+ }
+
+ if (MR_io_tabling_start_event_num == 0) {
+ /* I/O tabling wasn't ever turned on */
+ return MR_FALSE;
+ }
+
+ if (retry_event_num < MR_io_tabling_start_event_num) {
+ /* I/O tabling was turned on, but after the retry event */
+ return MR_FALSE;
+ }
+
+ if ((MR_io_tabling_stop_event_num > 0)
+ && (MR_io_tabling_stop_event_num < cur_event_num))
+ {
+ /* I/O tabling was turned off before the current event */
+ return MR_FALSE;
+ }
+
+ return MR_TRUE;
+}
+
/*
** This function figures out the state of the stacks (i.e. the values of MR_sp,
** MR_curfr and MR_maxfr) just after entry to the procedure specified by the
@@ -968,8 +1002,7 @@
return NULL;
}
- MR_maybe_record_call_table(level_layout,
- *base_sp_ptr, *base_curfr_ptr);
+ MR_maybe_record_call_table(level_layout, *base_sp_ptr, *base_curfr_ptr);
#ifdef MR_DEBUG_RETRY_STACKS
MR_print_detstackptr(MR_mdb_out, *sp_ptr);
@@ -987,8 +1020,7 @@
if (*problem == NULL) {
*problem = "not that many ancestors";
} else if (MR_streq(*problem, "reached unknown label")) {
- *problem = "cannot retry "
- "across non-debuggable region";
+ *problem = "cannot retry across non-debuggable region";
}
return NULL;
@@ -1041,8 +1073,7 @@
*/
if (! MR_PROC_LAYOUT_HAS_EXEC_TRACE(level_layout)) {
- return "an intervening stack frame "
- "has no debugging information";
+ return "an intervening stack frame has no debugging information";
} else if (level_layout->MR_sle_maybe_maxfr > 0) {
*maxfr_ptr = (MR_Word *) MR_based_stackvar(level_sp,
level_layout->MR_sle_maybe_maxfr);
@@ -1054,9 +1085,8 @@
} /* else we need do nothing */
} else {
/*
- ** When we finish setting up the stack frame of a
- ** procedure that lives on the nondet stack,
- ** maxfr == curfr.
+ ** When we finish setting up the stack frame of a procedure that lives
+ ** on the nondet stack, maxfr == curfr.
*/
*maxfr_ptr = level_curfr;
@@ -1082,13 +1112,11 @@
if (i < MR_long_desc_var_count(label_layout)) {
return MR_lookup_long_lval_base(
MR_long_desc_var_locn(label_layout, i),
- saved_regs, base_sp, base_curfr,
- succeeded);
+ saved_regs, base_sp, base_curfr, succeeded);
} else {
return MR_lookup_short_lval_base(
MR_short_desc_var_locn(label_layout, i),
- saved_regs, base_sp, base_curfr,
- succeeded);
+ saved_regs, base_sp, base_curfr, succeeded);
}
}
}
@@ -1202,14 +1230,12 @@
return MR_RETRY_ERROR;
}
- if (MR_sle_eval_method(proc_layout) != MR_EVAL_METHOD_MINIMAL)
- {
+ if (MR_sle_eval_method(proc_layout) != MR_EVAL_METHOD_MINIMAL) {
continue;
}
if (proc_layout->MR_sle_maybe_call_table <= 0) {
- MR_fatal_error("minimal model procedure "
- "has no call table slot");
+ MR_fatal_error("minimal model procedure has no call table slot");
}
trienode = (MR_TrieNode) MR_based_framevar(cur_maxfr,
@@ -1232,8 +1258,7 @@
if (cur_maxfr == MR_gen_stack[cur_gen].generator_frame) {
for (i = 0; i < record_ptr_next; i++) {
if (record_ptrs[i].record_leader == subgoal) {
- record_ptrs[i].found_leader_generator
- = MR_TRUE;
+ record_ptrs[i].found_leader_generator = MR_TRUE;
}
}
@@ -1329,12 +1354,10 @@
case MR_EVAL_METHOD_MEMO:
case MR_EVAL_METHOD_LOOP_CHECK:
if (MR_DETISM_DET_STACK(level_layout->MR_sle_detism)) {
- call_table = (MR_TrieNode) MR_based_stackvar(
- base_sp,
+ call_table = (MR_TrieNode) MR_based_stackvar(base_sp,
level_layout->MR_sle_maybe_call_table);
} else {
- call_table = (MR_TrieNode) MR_based_framevar(
- base_curfr,
+ call_table = (MR_TrieNode) MR_based_framevar(base_curfr,
level_layout->MR_sle_maybe_call_table);
}
@@ -1342,8 +1365,7 @@
MR_ensure_room_for_next(MR_call_table_ptr, MR_TrieNode,
INIT_CALL_TABLE_ARRAY_SIZE);
- MR_call_table_ptrs[MR_call_table_ptr_next] =
- call_table;
+ MR_call_table_ptrs[MR_call_table_ptr_next] = call_table;
MR_call_table_ptr_next++;
}
Index: trace/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.h,v
retrieving revision 1.26
diff -u -b -r1.26 mercury_trace.h
--- trace/mercury_trace.h 15 May 2002 11:24:18 -0000 1.26
+++ trace/mercury_trace.h 28 Oct 2002 11:32:56 -0000
@@ -107,15 +107,25 @@
** when it finds that some of the stack frames it looks at lack debugging
** information.
**
-** Retry across I/O is unsafe in general, at least for now. It is therefore
-** allowed only
+** Retry across I/O is unsafe in general. It is therefore allowed only if one
+** of the following is true.
**
-** - if unconditional_allow_io is TRUE, or
-** - if in_fp and out_fp are both non-NULL, and the user, when asked whether
-** he/she wants to perform the retry anyway, says yes.
+** - If the retry is in a tabled region, and we believe that all I/O actions
+** are tabled, either because we are in a grade in which all I/O actions
+** really are tabled or because the caller tells us to assume so.
+** - If across_io is MR_RETRY_IO_FORCE.
+** - If across_io is MR_RETRY_IO_INTERACTIVE (in which case in_fp and out_fp
+** must both be non-NULL), and the user, when asked whether he/she wants
+** to perform the retry anyway, says yes.
*/
typedef enum {
+ MR_RETRY_IO_FORCE,
+ MR_RETRY_IO_INTERACTIVE,
+ MR_RETRY_IO_ONLY_IF_SAFE
+} MR_Retry_Across_Io;
+
+typedef enum {
MR_RETRY_OK_DIRECT,
MR_RETRY_OK_FINISH_FIRST,
MR_RETRY_OK_FAIL_FIRST,
@@ -125,7 +135,8 @@
extern MR_Retry_Result MR_trace_retry(MR_Event_Info *event_info,
MR_Event_Details *event_details,
int ancestor_level,
- MR_bool unconditional_allow_io,
+ MR_Retry_Across_Io across_io,
+ MR_bool assume_all_io_is_tabled,
const char **problem,
FILE *in_fp, FILE *out_fp,
MR_Code **jumpaddr);
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.60
diff -u -b -r1.60 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c 30 Oct 2002 01:25:35 -0000 1.60
+++ trace/mercury_trace_declarative.c 30 Oct 2002 06:50:50 -0000
@@ -230,6 +230,8 @@
static void MR_decl_checkpoint_loc(const char *str,
MR_Trace_Node node);
+MR_bool MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
+
MR_Code *
MR_trace_decl_debug(MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info)
{
@@ -1111,8 +1113,8 @@
out = fopen(outfile, "w");
if (out == NULL) {
fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: cannot open file `%s' "
- "for output: %s.\n",
+ fprintf(MR_mdb_err,
+ "mdb: cannot open file `%s' for output: %s.\n",
outfile, strerror(errno));
return MR_FALSE;
} else {
@@ -1125,8 +1127,8 @@
MR_trace_decl_ensure_init();
depth_limit = event_info->MR_call_depth + MR_EDT_DEPTH_STEP_SIZE;
message = MR_trace_start_collecting(event_info->MR_event_number,
- event_info->MR_call_seqno, depth_limit, cmd,
- event_info, event_details, jumpaddr);
+ event_info->MR_call_seqno, depth_limit, cmd, event_info,
+ event_details, jumpaddr);
if (message == NULL) {
return MR_TRUE;
@@ -1166,8 +1168,7 @@
static const char *
MR_trace_start_collecting(MR_Unsigned event, MR_Unsigned seqno,
- MR_Unsigned maxdepth,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
+ MR_Unsigned maxdepth, MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
MR_Event_Details *event_details, MR_Code **jumpaddr)
{
const char *problem;
@@ -1176,8 +1177,10 @@
/*
** Go back to an event before the topmost call.
*/
- retry_result = MR_trace_retry(event_info, event_details, 0, MR_TRUE,
- &problem, NULL, NULL, jumpaddr);
+ retry_result = MR_trace_retry(event_info, event_details, 0,
+ MR_RETRY_IO_ONLY_IF_SAFE,
+ MR_trace_decl_assume_all_io_is_tabled, &problem, NULL, NULL,
+ jumpaddr);
if (retry_result != MR_RETRY_OK_DIRECT) {
if (retry_result == MR_RETRY_ERROR) {
return problem;
@@ -1369,7 +1372,9 @@
MR_print_stack_regs(stdout, event_info->MR_saved_regs);
MR_print_succip_reg(stdout, event_info->MR_saved_regs);
#endif
- retry_result = MR_trace_retry(event_info, event_details, 0, MR_TRUE,
+ retry_result = MR_trace_retry(event_info, event_details, 0,
+ MR_RETRY_IO_ONLY_IF_SAFE,
+ MR_trace_decl_assume_all_io_is_tabled,
&problem, NULL, NULL, &jumpaddr);
#ifdef MR_DEBUG_RETRY
MR_print_stack_regs(stdout, event_info->MR_saved_regs);
Index: trace/mercury_trace_declarative.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_declarative.h,v
retrieving revision 1.15
diff -u -b -r1.15 mercury_trace_declarative.h
--- trace/mercury_trace_declarative.h 16 Oct 2002 05:45:30 -0000 1.15
+++ trace/mercury_trace_declarative.h 29 Oct 2002 09:44:42 -0000
@@ -32,6 +32,24 @@
MR_Event_Details *event_details, MR_Code **jumpaddr);
/*
+** The declarative debugger may need to perform many retries during one
+** diagnosis session. If the goal being debugged can do I/O, these retries
+** are safe only if all I/O primitives in the program are tabled. Normally,
+** this is guaranteed by the grade being a debugging grade. However, we also
+** want to check the functioning of the declarative debugger in non-debug
+** grades. In these grades, we only call tabled I/O primitives in the test
+** cases themselves, so the existence of non-tabled primitives in the standard
+** library doesn't matter. An option of the dd (or dd_dd) command can assert
+** that all the I/O primitives being backtracked over are tabled. This global
+** variable records the presence or absence of this option on the last dd or
+** dd_dd command. It must be stored in a global instead of being passed around
+** as a parameter because the front end can cause retries even after the
+** initial retry that starts collecting the annotated trace.
+*/
+
+extern MR_bool MR_trace_decl_assume_all_io_is_tabled;
+
+/*
** The following macros are provided to help C code manipulate the
** Mercury data structure. The values here must match the corresponding
** values in the definitions in browser/declarative_execution.m.
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.66
diff -u -b -r1.66 mercury_trace_external.c
--- trace/mercury_trace_external.c 5 Aug 2002 21:46:18 -0000 1.66
+++ trace/mercury_trace_external.c 28 Oct 2002 11:53:21 -0000
@@ -619,8 +619,9 @@
"REQUEST_RETRY\n");
}
retry_result = MR_trace_retry(event_info,
- &event_details, 0, MR_FALSE, &message,
- NULL, NULL, &jumpaddr);
+ &event_details, 0,
+ MR_RETRY_IO_ONLY_IF_SAFE, MR_FALSE,
+ &message, NULL, NULL, &jumpaddr);
if (retry_result == MR_RETRY_OK_DIRECT) {
MR_send_message_to_socket("ok");
cmd->MR_trace_cmd = MR_CMD_GOTO;
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.145
diff -u -b -r1.145 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 24 Oct 2002 16:30:38 -0000 1.145
+++ trace/mercury_trace_internal.c 30 Oct 2002 03:46:56 -0000
@@ -468,7 +468,8 @@
static MR_bool MR_trace_options_strict_print(MR_Trace_Cmd_Info *cmd,
char ***words, int *word_count,
const char *cat, const char *item);
-static MR_bool MR_trace_options_retry(MR_bool *allow_io,
+static MR_bool MR_trace_options_retry(MR_Retry_Across_Io *across_io,
+ MR_bool *assume_all_io_is_tabled,
char ***words, int *word_count,
const char *cat, const char *item);
static MR_bool MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
@@ -501,6 +502,9 @@
int *timeout, MR_bool *force, MR_bool *verbose,
MR_bool *split, MR_bool *close_window, char ***words,
int *word_count, const char *cat, const char*item);
+static MR_bool MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
+ char ***words, int *word_count,
+ const char *cat, const char *item);
static void MR_trace_usage(const char *cat, const char *item);
static void MR_trace_do_noop(void);
@@ -1592,12 +1596,14 @@
{
int n;
int ancestor_level;
- MR_bool force_retry;
+ MR_Retry_Across_Io across_io;
const char *problem;
MR_Retry_Result result;
+ MR_bool assume_all_io_is_tabled;
- force_retry = MR_FALSE;
- if (! MR_trace_options_retry(&force_retry,
+ across_io = MR_RETRY_IO_INTERACTIVE;
+ assume_all_io_is_tabled = MR_FALSE;
+ if (! MR_trace_options_retry(&across_io, &assume_all_io_is_tabled,
&words, &word_count, "backward", "retry"))
{
; /* the usage message has already been printed */
@@ -1610,16 +1616,15 @@
return KEEP_INTERACTING;
}
- if (ancestor_level == 0 &&
- MR_port_is_entry(event_info->MR_trace_port))
+ if (ancestor_level == 0 && MR_port_is_entry(event_info->MR_trace_port))
{
MR_trace_do_noop();
return KEEP_INTERACTING;
}
result = MR_trace_retry(event_info, event_details,
- ancestor_level, force_retry, &problem,
- MR_mdb_in, MR_mdb_out, jumpaddr);
+ ancestor_level, across_io, assume_all_io_is_tabled,
+ &problem, MR_mdb_in, MR_mdb_out, jumpaddr);
switch (result) {
case MR_RETRY_OK_DIRECT:
@@ -1637,7 +1642,7 @@
cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
/* Arrange to retry the call once it is finished. */
- MR_insert_line_at_head("retry -f");
+ MR_insert_line_at_head("retry -o");
return STOP_INTERACTING;
case MR_RETRY_OK_FAIL_FIRST:
@@ -1648,7 +1653,7 @@
cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
/* Arrange to retry the call once it is finished. */
- MR_insert_line_at_head("retry -f");
+ MR_insert_line_at_head("retry -o");
return STOP_INTERACTING;
case MR_RETRY_ERROR:
@@ -3195,6 +3200,8 @@
MR_io_tabling_phase = MR_IO_TABLING_DURING;
MR_io_tabling_start = MR_io_tabling_counter;
MR_io_tabling_end = MR_IO_ACTION_MAX;
+ MR_io_tabling_start_event_num =
+ event_info->MR_event_number;
#ifdef MR_DEBUG_RETRY
MR_io_tabling_debug = MR_TRUE;
#endif
@@ -3229,6 +3236,8 @@
{
MR_io_tabling_phase = MR_IO_TABLING_AFTER;
MR_io_tabling_end = MR_io_tabling_counter_hwm;
+ MR_io_tabling_stop_event_num =
+ event_info->MR_event_number;
fprintf(MR_mdb_out, "io tabling stopped\n");
} else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER)
{
@@ -3542,15 +3551,17 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
- if (word_count != 1) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "mdb: dd requires no arguments.\n");
- } else {
+ MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
+ if (! MR_trace_options_dd(&MR_trace_decl_assume_all_io_is_tabled,
+ &words, &word_count, "dd", "dd"))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
if (MR_trace_have_unhid_events) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err,
- "mdb: dd doesn't work after `unhide_events on'.\n");
+ "mdb: dd doesn't work "
+ "after `unhide_events on'.\n");
return KEEP_INTERACTING;
}
@@ -3559,6 +3570,8 @@
{
return STOP_INTERACTING;
}
+ } else {
+ MR_trace_usage("dd", "dd");
}
return KEEP_INTERACTING;
@@ -3572,11 +3585,12 @@
MR_Trace_Mode trace_mode;
const char *filename;
- if (word_count > 2) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "mdb: dd_dd takes at most one argument.\n");
- } else {
+ MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
+ if (! MR_trace_options_dd(&MR_trace_decl_assume_all_io_is_tabled,
+ &words, &word_count, "dd", "dd_dd"))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count <= 2) {
if (word_count == 2) {
trace_mode = MR_TRACE_DECL_DEBUG_DUMP;
filename = (const char *) words[1];
@@ -3590,6 +3604,8 @@
{
return STOP_INTERACTING;
}
+ } else {
+ MR_trace_usage("dd", "dd_dd");
}
return KEEP_INTERACTING;
@@ -3823,24 +3839,40 @@
static struct MR_option MR_trace_retry_opts[] =
{
- { "allow-io", MR_no_argument, NULL, 'a' },
+ { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
+ { "force", MR_no_argument, NULL, 'f' },
+ { "interactive", MR_no_argument, NULL, 'i' },
+ { "only-if-safe", MR_no_argument, NULL, 'o' },
{ NULL, MR_no_argument, NULL, 0 }
};
static MR_bool
-MR_trace_options_retry(MR_bool *force_retry,
+MR_trace_options_retry(MR_Retry_Across_Io *across_io,
+ MR_bool *assume_all_io_is_tabled,
char ***words, int *word_count, const char *cat, const char *item)
{
int c;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "f",
+ while ((c = MR_getopt_long(*word_count, *words, "afio",
MR_trace_retry_opts, NULL)) != EOF)
{
switch (c) {
+ case 'a':
+ *assume_all_io_is_tabled = MR_TRUE;
+ break;
+
case 'f':
- *force_retry = MR_TRUE;
+ *across_io = MR_RETRY_IO_FORCE;
+ break;
+
+ case 'i':
+ *across_io = MR_RETRY_IO_INTERACTIVE;
+ break;
+
+ case 'o':
+ *across_io = MR_RETRY_IO_ONLY_IF_SAFE;
break;
default:
@@ -4364,6 +4396,39 @@
return MR_TRUE;
}
+static struct MR_option MR_trace_dd_opts[] =
+{
+ { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
+ char ***words, int *word_count, const char *cat, const char *item)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "a", MR_trace_dd_opts,
+ NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'a':
+ *assume_all_io_is_tabled = MR_TRUE;
+ break;
+
+ default:
+ MR_trace_usage(cat, item);
+ return MR_FALSE;
+ }
+ }
+
+ *words = *words + MR_optind - 1;
+ *word_count = *word_count - MR_optind + 1;
+ return MR_TRUE;
+}
+
static void
MR_trace_usage(const char *cat, const char *item)
/* cat is unused now, but could be used later */
@@ -4996,6 +5061,13 @@
{"-N", "-S", "-a", "-n", "-s",
"--none", "--some", "--all", "--strict", "--no-strict", NULL};
+/*
+** "retry --assume-all-io-is-tabled" is deliberately not documented as
+** it is for developers only.
+*/
+static const char *const MR_trace_retry_cmd_args[] =
+ {"--force", "--interactive", "--only-if-safe", NULL};
+
static const char *const MR_trace_print_cmd_args[] =
{"-f", "-p", "-v", "--flat", "--pretty", "--verbose",
"exception", "goal", "*", NULL};
@@ -5088,7 +5160,7 @@
MR_trace_movement_cmd_args, MR_trace_null_completer },
{ "backward", "retry", MR_trace_cmd_retry,
- NULL, MR_trace_null_completer },
+ MR_trace_retry_cmd_args, MR_trace_null_completer },
{ "browsing", "level", MR_trace_cmd_level,
MR_trace_stack_cmd_args, MR_trace_null_completer },
@@ -5166,6 +5238,15 @@
{ "help", "help", MR_trace_cmd_help,
NULL, MR_trace_help_completer },
+ { "misc", "source", MR_trace_cmd_source,
+ MR_trace_source_cmd_args, MR_trace_filename_completer },
+ { "misc", "save", MR_trace_cmd_save,
+ NULL, MR_trace_filename_completer },
+ { "misc", "dd", MR_trace_cmd_dd,
+ NULL, MR_trace_null_completer},
+ { "misc", "quit", MR_trace_cmd_quit,
+ MR_trace_quit_cmd_args, NULL},
+
#ifdef MR_TRACE_HISTOGRAM
{ "exp", "histogram_all", MR_trace_cmd_histogram_all,
NULL, MR_trace_filename_completer },
@@ -5195,17 +5276,7 @@
MR_trace_on_off_args, MR_trace_null_completer },
{ "developer", "unhide_events", MR_trace_cmd_unhide_events,
MR_trace_on_off_args, MR_trace_null_completer },
-
- { "misc", "source", MR_trace_cmd_source,
- MR_trace_source_cmd_args, MR_trace_filename_completer },
- { "misc", "save", MR_trace_cmd_save,
- NULL, MR_trace_filename_completer },
- { "misc", "quit", MR_trace_cmd_quit,
- MR_trace_quit_cmd_args, NULL},
-
- { "dd", "dd", MR_trace_cmd_dd,
- NULL, MR_trace_null_completer},
- { "dd", "dd_dd", MR_trace_cmd_dd_dd,
+ { "developer", "dd_dd", MR_trace_cmd_dd_dd,
NULL, MR_trace_filename_completer},
/* End of doc/mdb_command_list. */
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list