Debuggers for logic programming languages have traditionally had a capability
most other debuggers did not: the ability to jump back to a previous state of
the program, effectively travelling back in time in the history of the
computation. This ``retry'' capability is very useful, allowing programmers to
examine in detail a part of the computation that they previously stepped over.
Unfortunately, it also creates a problem: while the debugger may be able to
restore the previous values of variables, it cannot restore the part of the
program's state that is affected by I/O operations. If the part of the
computation being jumped back over performs I/O, then the program will perform
these I/O operations twice, which will result in unwanted effects ranging from
the benign (e.g. output appearing twice) to the fatal (e.g. trying to close an
already closed file). We present a simple mechanism for ensuring that every I/O
action called for by the program is executed at most once, even if the
programmer asks the debugger to travel back in time from after the action to
before the action. The overhead of this mechanism is low enough and can be
controlled well enough to make it practical to use it to debug computations
that do significant amounts of I/O.Comment: In M. Ronsse, K. De Bosschere (eds), proceedings of the Fifth
International Workshop on Automated Debugging (AADEBUG 2003), September 2003,
Ghent. cs.SE/030902