  Backtracking (i.e., reverse execution) helps the user of a debugger to
naturally think backwards along the execution path of a program, and thinking
backwards makes it easy to locate the origin of a bug. So far backtracking has
been implemented mostly by state saving or by checkpointing. These
implementations, however, inherently do not scale. Meanwhile, a more recent
backtracking method based on reverse-code generation seems promising because
executing reverse code can restore the previous states of a program without
state saving. In the literature, there can be found two methods that generate
reverse code: (a) static reverse-code generation that pre-generates reverse
code through static analysis before starting a debugging session, and (b)
dynamic reverse-code generation that generates reverse code by applying dynamic
analysis on the fly during a debugging session. In particular, we espoused the
latter one in our previous work to accommodate non-determinism of a program
caused by e.g., multi-threading. To demonstrate the usefulness of our dynamic
reverse-code generation, this article presents a case study of various
backtracking methods including ours. We compare the memory usage of various
backtracking methods in a simple but nontrivial example, a bounded-buffer
program. In the case of non-deterministic programs such as this bounded-buffer
program, our dynamic reverse-code generation outperforms the existing
backtracking methods in terms of memory efficiency.
