| Updated: 04 December 1998 |
| An Annotated Bibliography on
Debugging Optimized Code Ronald F. Brender 1 June 1998 The following is a complete bibliography on the subject of debugging optimized code (excluding debugging of parallel programs). Each citation is annotated with a summary of the material presented. A paper whose summary begins with "[+]" is recommended as especially interesting and useful. Adl-Tabatabi, Ali-Reza. "Nonresident and Endangered Variables: The Effects of Code Generation Optimizations on Symbolic Debugging." Carnegie Mellon University, CMU-CS-92-221, December 1992. 33pp. Adl-Tabatabi, Ali-Reza. "Source-Level Debugging of Globally Optimized Code." Ph.D. dissertation, Carnegie Mellon University, CMU-CS-96-133, June 1996. Adl-Tabatabi, Ali-Reza. "Symbolic Debugging of Globally Optimized Code: Data Value Problems and Their Solutions." Carnegie Mellon University, CMU-CS-95-105, January 1994. 16pp. Adl-Tabatabi, Ali-Reza and Thomas Gross. "Detection and Recovery of Endangered Variables Caused by Instruction Scheduling." ACM SIGPLAN Programming Language Design and Implementation, Albuquerque, New Mexico, June 1993. SIGPLAN Notices, vol. 28, no. 6 (1993): 13-25. Adl-Tabatabi, Ali-Reza and Thomas Gross. "Evicted Variables and the Interaction of Global Register Allocation and Symbolic Debugging." Carnegie Mellon University, CMU-CS-92-202, October 1992. 16pp. [+] The four papers (which appear first, third, fourth, and fifth in the list of five) examine the effects of instruction scheduling and how it interacts with the ability to debug the resulting code. In particular, these papers describe the means to identify variables whose values are known to be available and current, unknown, or suspect (endangered). Measurements on an experimental implementation confirm the utility of the approach. The second paper (CMU-CS95-105) extends the techniques to the results of local and global optimization more generally. All four papers present substantially similar material but in varying focus, depth and completeness. The first paper (CMU-CS-92-221) is the most thorough and complete including, in particular, extensive results from experimental measurements of effectiveness. The last paper (CMU-CS-92-202) is a preliminary version of the fourth paper (PLDI 1993). The thesis (CMU-CS-96-133) combines the material covered in the four papers into a comprehensive whole. The thesis also incorporates material that deals with the setting of breakpoints and the reporting of program locations. The authors propose a model for describing source-to-object and object-to-source mappings (to be used in an object file) and evaluate this model against the effects of the most common forms of global optimization. Brooks, Gary, Gilbert J. Hansen, and Steve Simmons. "A New Approach to Debugging Optimized Code." ACM SIGPLAN '92 Conference on Programming Language Design and Implementation, SIGPLAN Notices, vol. 27, no. 7 (July 1992): 1-11. [+] This paper sketches the implementation techniques used in the CONVEX compilers and debugger to support debugging of optimized code. The focus of the paper is on the compiler-debugger interfaces (CDIs) that convey the needed information from compile time to debug time. The following tables are used:
This factorization of information is chosen to facilitate incremental reading/loading of symbol information only as needed to respond to user queries. Example displays are presented with explanation of how the effects of optimization are communicated to a user. Performance measurements suggest that creating the described CDIs costs an additional one-third in compile time (compared to a 4 percent increase for stabs [UNIX symbol table structures]) and that the CDI information is about two-thirds larger than stab information. Bruegge, Bernd. "Debugging Ada." Carnegie-Mellon University, CMU-CS-85-127, 3 May 1985. 33pp. A brief, even superficial, overview of how to handle many of the newer aspects of Ada in a debugger. Procedure inlining and generic instantiations are discussed using the techniques described by Zellweger (only the PARC technical report was known at the time of this paper). Other "optimization" issues are not discussed. Chase, Benjamin B. "Intermediate Languages for Debuggers." Rice COMP TR90-116, May 1990. 20pp. This paper is an elaboration of the technical report by Chase et al, Rice COMP TR89-90, April 1989, that proposes a debugger organized to parallel the phases of an optimizing compiler and communicating with later phases using an augmented compiler-like intermediate language. The intent is that each debugger phase would be responsible for augmenting the intermediate language with the information needed for the debugger run-time support to unravel the optimization achieved by the corresponding compiler phase. No details or concrete demonstrations of feasibility are given. CONVEX Computer Corporation. CONVEX CXdb Concepts. Richardson, Texas: CONVEX Press, Order No. DSW-471, May 1991. 59pp. This book describes the CONVEX debugger, including in particular its support for debugging optimized code. Code compiled with optimization levels up through -O1, which includes global optimization within a procedure, can be debugged. Key to the debugger graphical interface is simultaneous display of the source and the corresponding machine code: the current point of execution is displayed in both. The book summarizes the capabilities of the debugger as follows:
As a usage-oriented guide, however, this book does not describe any of the internal mechanisms or representations used to accomplish these capabilities. Cool, Lyle E. "Debugging VLIW Code After Instruction Scheduling." Master's thesis, Oregon Graduate Center, University of Portland, July 1992. 84pp. This thesis considers the problems of variable examination and execution stepping in VLIW code after instruction scheduling; however, the presentation does not show how VLIW-ness really matters compared to RISC processors in general. The emphasis is on graphical techniques for displaying execution progress, in particular, abandoning traditional line-oriented conceptualizations. Implementation techniques are evaluated and alternative designs compared. No new theoretical results are presented. Copperman, Max. "Debugging Optimized Code Without Being Misled." Ph.D. dissertation, University of California at Santa Cruz, UCSC Technical Report UCSC-CRL-93-21, 11 June 1993. 144pp. [+] This thesis contains three parts. Part I presents the usual introduction and background material, although in an unusually effective way. Part II presents a way to produce an accurate call-stack trace -- and appears to be substantially the same as UCSC-CRL-92-25, whose citation follows. Part III, the most important part, presents a thorough treatment of currency determination. In particular, it eliminates most of the restrictions and simplifying assumptions that have appeared in prior publications. While no implementation is described, there is a reasonably good description of a viable implementation approach, including cost and complexity analysis. The heart of the technique is a means to create a mapping from the initial, naive flow graph of the source to the flow graph of the object code and to continuously maintain and update that mapping as compiler optimization progresses. The technique is general enough to handle most optimizations, including those that modify the shape of the flow graph. In this presentation, the compiler outputs a representation of the source/object mapping for direct use by the debugger in responding to user queries. Whether this representation might usefully be further preprocessed into a simpler form for debug-time use is not considered. Copperman, Max. "Producing an Accurate Call-Stack Trace in the Occasional Absence of Frame Pointers." University of California at Santa Cruz, UCSC Technical Report UCSC-CRL-92-25, March 1992 (supersedes UCSC-CRL-90-62). 16pp. [+] "The method used today by interactive debuggers to provide a call-stack trace relies on a frame pointer being set up within the stack frame of each active frame. This paper gives several methods that support a debugger's call-stack trace facility in the circumstance that, due to optimization, some routines do not set up a frame pointer. These methods vary in cost: there is a trade-off between run-time overhead for the debugger and required symbol table and compiler support." Copperman, Max and Charles E. McDowell. "A Further Note on Hennessy's 'Symbolic Debugging of Optimized Code.'" ACM Transactions on Programming Languages and Systems, vol. 15, no. 2 (April 1993): 357-365. This paper describes a key limitation in the Hennessy algorithms, namely the assumption that there is only one assignment to a variable in a basic block. The paper shows that when this assumption is false, the algorithms will indicate that a variable is noncurrent at points where the current value is in fact available. Related work with improved results is cited but not discussed. Coutant, Deborah S., Sue Meloy, and Michelle Ruscetta. "DOC: A Practical Approach to Source-Level Debugging of Globally Optimized Code." Proceedings of the SIGPLAN '88 Conference on Programming Language Design and Implementation, Atlanta, Georgia (22-24 June 1988): 125-134. [+] This paper describes techniques developed in the DOC debugger for the HP9000 Series 800 to deal with certain kinds of optimization in compiled code. The focus is on register promotion and assignment, loop variable elimination (induction variable elaboration), and instruction scheduling. These are considered "data value" problems, while "code location" problems are not addressed (and are claimed to be less important in practice). As a simplifying assumption, data and control flow modification are not allowed. The primary means to pass information from the compiler to the debugger are so-called range entries. The authors sketch algorithms for creating these entries in the compiler and using them in the debugger. Performance assessment indicates that the incremental space/time to create and use these structures is quite small. Feiler, Peter H. "A Language-Oriented Interactive Programming Environment Based on Compilation Technology." Ph.D. dissertation, Carnegie-Mellon University, CMU-CS-82-117, May 1982. 168pp. This dissertation explores techniques for achieving the effect/benefits of interactive/interpretive techniques using as much static compilation-based technology as possible. There is substantial discussion of ways to track, maintain, and reestablish consistency between the primary (tree-based) program representation and the derivative compiled code in the face of both debugging actions (breakpoints and the like) and arbitrary program modification of a live, executing program. While the degree of integration is rather more than might be thought feasible, it does entail substantial constraints on the degree to which the more highly optimized parts of the program can be effectively debugged. Hennessy, John. "Symbolic Debugging of Optimized Code." ACM Transactions on Programming Languages and Systems, vol. 4, no. 3 (July 1982): 323-344. (This is a revised version of a report of the same title published as Stanford CSL report SEL 79-026, July 1979.) [+] This paper presents an analysis of a model of both local and global optimization and related code generation and derives algorithms for detecting when a variable is noncurrent (does not hold its expected value) and for recovering its correct value. Empirical results for local (basic block) optimizations suggest that perhaps 20 percent of basic blocks have noncurrent variables and in a bit more than half of those cases the correct value can be recovered. For global optimization, detection is harder and not always definitely possible (a variable may or may not be current at a certain point depending on what path got there); recovery of the correct value is feasible for variables involved in test replacement but rarely possible in the cases of code motion and dead-store elimination. A key concept in the approach is that the compiler provides the complete flow graph of the optimized program to the debugger so that the debugger is able to solve certain flow graph problems at run-time. Holzle, Urs, Craig Chambers, David Ungar. "Debugging Optimized Code with Dynamic Deoptimization." ACM SIGPLAN '92 Conference on Programming Language Design and Implementation, San Francisco, California, 17-19 June 1992. SIGPLAN NOTICES, vol. 27, no. 7 (July 1992): 32-43. [+] This paper describes a debugging system for the object-oriented language SELF that provides "complete" source-level debugging (expected behavior) of optimized code. Dynamic deoptimization (replacement of the code and activation of the top most procedure on the call stack with an unoptimized equivalent) is used to implement many debug actions. The technique depends on delaying asynchronous events to well-defined interruption points (backward branches and calls), at which the debugging information applies. Optimization between interrupt points is unrestricted. (At least some of the restrictions on optimization are also required for garbage collection.) Application to pointer-unsafe languages is problematical: many more interrupt points become necessary, which results in a more severe negative effect on optimization. Iyengar, Arun K., Thaddeus S. Grzesik, Valerie J. Ho-Gibson, Tracy A. Hoover, and John R. Vasta. "An Event-Based, Retargetable Debugger." Hewlett-Packard Journal (December 1994): 33-43. This paper presents a general overview of the Hewlett-Packard Distributed Debugging Environment (DDE) Debugger, which runs on a number of operating systems, including HP-UX*, Domain/OS 68K, Domain/OS Prism, SPARC Solaris, and PA-RISC OSF/1. The level of detail is insufficient to tell very much -- the debugger does appear to be relatively full featured and multilingual, has a GUI, and has been extended and ported enough times to different environments that they evolved to a good implementation partitioning. Debugging optimized code is briefly discussed, but the only support actually mentioned is a kind of split lifetime support on Domain/OS systems and some kind of many-to-many source line--to--instruction mapping on Domain/OS and HP-UX* systems. LaFrance-Linden, David C. P. "Challenges in Designing an HPF Debugger." Digital Technical Journal, vol. 9, no. 3 (1997): 50-64. This paper focuses on the unusual problems of debugging of High Performance FORTRAN (HPF) programs that have been optimized into parallel threads and/or multiple processes executing on one or more processors. Here a conceptually single-thread program is transformed into a parallel program, and the debugger has to interpret the state of that program in terms of the original nonparallel one. The paper mentions possible adaptation to more traditional debugging optimized code support, but these ideas are not much developed. Podgursku, Andy and Lori A. Clarke. "A Formal Model of Program Dependences and Its Implications for Software Testing, Debugging and Maintenance." IEEE Transactions on Software Engineering, vol. 16, no. 9 (September 1990): 965-979. "A formal, general model of program dependences is presented and used to evaluate several dependence-based software testing, debugging and maintenance techniques. Two generalizations of control and data dependence, called weak and strong syntactic dependence, are introduced and related to a concept called semantic dependence.... These results are then used to support some proposed uses of program dependences, to controvert others, and to suggest some new ones." While it does not direct address the pragmatic issues of debugging optimized code, this paper is interesting because it provides a concise but thorough formalization of many of the concepts that underlie both the origin of and approaches to this problem. Pollock, Lori, Mary Bivens, and Mary Lou Soffa. "Debugging Optimized Code via Tailoring." International Symposium on Software Testing and Analysis (August 1994). "This paper presents a new approach to the problem of debugging optimized code. By employing techniques from incremental optimization analysis, optimizations are tailored to the type and context of debugging commands. There are no a priori restrictions placed on either debugging commands or optimizations. In response to a request specified during debugging, an optimization profile is used to determine if the expected response can be provided by the debugger. When an optimization inhibits transparently servicing the request, the profile is then used to recover the desired information or to tailor the code in such a way that the debugging request can be honored transparently in a subsequent execution. Unnecessary limitations are avoided by basing the optimization on the conflicts with the user's current debugging requests rather than with the entire repertoire of debugging commands." Pollock, Lori L. and Mary Lou Soffa. "High-level Debugging with the Aid of an Incremental Optimizer." Proceedings of the 21st Hawaii International Conference on System Sciences (January 1988): 524-532. "Although a high-level debugger is extremely useful in program development, its utility when program code is optimized is severely hindered by optimizing code transformations. This paper presents the design of a high-level debugger that tailors optimizations to conform to desired debugging capabilities. In this scheme, debugging requests are specified before program execution and viewed as changes that inhibit optimizations in ways similar to program edits invalidating optimizations. Using techniques borrowed from incremental optimization, debugging requests are honored by detecting and temporarily disabling those optimizations that prohibit correct debugging response. An intermediate program representation keeps a history of all optimizations possible prior to debugging. Any modifications to debugging requests are incrementally incorporated into this representation which is then used to generate optimized code tailored to the new desired debugging capabilities. When debugging requests have little effect on optimizations, code closely related to the final optimized code is debugged. Execution time and debugging accuracy are always comparable to debugging unoptimized code as no additional analysis or optimization history is needed at run time." Implementation of a prototype system is "currently underway" so there is no user experience concerning the difficulty and effectiveness associated with having to predetermine the intended debugging actions. Since debugging can often lead in unexpected directions, the need for preplanning may not be viable in practice. Pollock, Lori L. and Mary Lou Soffa. "Incremental Global Optimization for Faster Recompilation." IEEE Proceedings of the International Conference on Computer Languages, New Orleans, Louisiana (March 1990): 281-290. This paper is similar in spirit to "High-level Debugging with the Aid of an Incremental Optimizer" by the same authors, but focuses on fast recompilation as such rather than on debugging support. Incremental optimization using an annotated program library is a central part of the mechanism. This paper is a preliminary version of "Incremental Global Reoptimization of Programs," whose citation follows. Pollock, Lori L. and Mary Lou Soffa. "Incremental Global Reoptimization of Programs." ACM TOPLAS, vol. 14, no. 2 (April 1992): 173-200. This paper details the formal and theoretical foundations for incremental program analysis and optimization that support and allow rapid recompilation and reoptimization in response to user editing activities. While these mechanisms can be used to support a kind of debugging of optimized code, this application is more usefully described in other papers. Seidner, Rich and Nick Tindall. "Interactive Debug Requirements." ACM SIGSOFT/SIGPLAN Software Engineering Symposium on High-Level Debugging, Pacific Grove, California (20-23 March 1983). ACM SIGPLAN Notices, vol. 18, no. 8 (August 1983): 9-22. [+] This paper presents a reasonable, if rather traditional (appropriate to 1983), formulation of requirements for a production-quality debugger. These requirements were developed by the SHARE user group for IBM systems but are broadly applicable. There is an interesting emphasis on the need to support debugging not just on "production code" (optimized) but even in "production environments" in the presence of the complete and live application complex. ("Debugging is more important at production-time than it is at application development time. When an application fails at production-time, work depending on that application stops.") Emphasis is on checking consistency of interfaces as a highly desirable adjunct to debugging per se. The following kinds of optimization are discussed as sources of difficulty:
Shu, William S. "Adapting a Debugger for Optimized Programs." ACM SIGPLAN Notices, vol. 28, no. 4 (April 1993): 39-44. This paper presents a very high-level view of a tool called Tracker that "mediates" between a compiler's optimizer and a run-time debugger. The idea is that Tracker somehow captures information at compile-time with little or no interaction with the base compiler and then uses this information at debug-time to unravel the effects of the optimization. The paper hints at a formal foundation but gives too little information to infer its nature. Most of the illustrations look like they follow the ideas of Zellweger. Srivastava, Amitabh. "Recovery of Noncurrent Variables in Source-Level Debugging of Optimized Code." Foundations of Software Technology and Theoretical Computer Science, Sixth Conference Proceedings. Nori, K. V. (ed.). Springer-Verlag (1986): 36-56. [+] Hennessy, in "Symbolic Debugging of Optimized Code," suggested various techniques and algorithms to identify noncurrent variables and possibly to recover the proper value. This paper extends (and corrects) these techniques. The algorithms developed can detect most of the recoverable variables and run in linear time. The paper also considers methods to limit the search to only part of the directed acyclic graph that represents the control flow. Streepy, L. "CXdb: A New View on Optimization." Proceedings of the Supercomputer Debugging Workshop, Albuquerque, New Mexico, November 1991. Tice, C. and S. Graham. "OPTVIEW: A New Approach for Examining Optimized Code." ACM SIGPLAN/SIGSOFT Workshop on Program Analysis for Software Tools and Engineering (PASTE '98), Montreal, Canada (16 June 1998). ACM SIGPLAN Notices, vol. 33, no. 7 (July 1998): 19-27. While not a debugger for optimized code, OPTVIEW might be part of one and shares many of the same problems of mapping an optimized binary back to the original source code. Rather than map directly, OPTVIEW creates a modified version of the source, intended to be still recognizable, that reflects some of the effects of optimization. Mapping a binary to this modified source should be easier than mapping to the original. A prototype implementation demonstrates the ideas and illustrates how the modified source might look. This paper contains only a cursory description of how the compiler passes information about what optimizations are performed for use by OPTVIEW. Wall, D., A. Srivastava, and R. Templin. "A Note on Hennessy's 'Symbolic Debugging of Optimized Code.'" ACM Transactions on Programming Languages and Systems, vol. 7, no. 1 (January 1985): 176-181. Wismuller, Roland. "Debugging of Globally Optimized Programs Using Data Flow Analysis." Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation, Orlando, Florida, 2024 June 1994. New York: Association of Computing Machinery (1994): 278-289. [+]"We deduce requirements on algorithms for currentness determination and present an algorithm meeting these requirements that is more general than previous work. We also give first experiences with an implementation." There are no restrictions on where the program is examined and indirect assignments via pointer variables are handled. Further, the technique does not depend on tracking the sequence of transformations as they are performed by a compiler, rather it builds a relationship data structure at the end of compilation. Wu, Le-Chun and Wen-mei W. Hwu. "A Novel Breakpoint Implementation Scheme for Debugging Optimized Code." University of Illinois, Urbana, Illinois, IMPACT Technical Report IMPACT-98-01, January 1998. 14pp. [+]In this paper, an "anchor point" associated with a desired breakpoint line is identified together with one or more "interception points," that is, instructions at which the debugger gains control early and then performs forward recovery until the anchor point it reached. Because interception points and anchor points may be in different basic blocks of the object code, escape points are also identified which mark where the forward scan should be abandoned because the anchor point will not be reached. During forward recovery, the effects of instructions on the (visible) machine state are recorded for subsequent use. The effects of overlapping interception to anchor point sequences and premature exception are taken into account. Compile-time flow graph algorithms for collecting the needed debugger symbol table information and debugger run-time data collection are concisely presented. Pragmatic limitations and compromises due to function calls (both inlined and not) and loops are discussed. Zellweger, Polle T. "An Interactive High-Level Debugger for Control-Flow Optimized Programs." Xerox PARC CSL-83-1, January 1983. 25pp. Zellweger, Polle T. "An Interactive High-Level Debugger for Control-Flow Optimized Programs." ACM SIGSOFT/SIGPLAN Software Engineering Symposium on High-Level Debugging, SIGPLAN Notices, vol. 18, no. 8 (August 1983): 159-171. This paper presents compiler and debugger algorithms that deal with two classes of control flow optimization: merging (such as procedure discovery and cross-jumping) and copying (such as loop unrolling and procedure inlining). The author discusses actual implementation in the Navigator debugger for the Cedar language. The SIGSOFT/SIGPLAN paper is a summary of the earlier report. Zellweger, Polle Trescott. "Interactive Source-Level Debugging of Optimized Programs." Ph.D. dissertation, University of California, Xerox PARC CSL-84-5 (May 1984). 270pp. [+] This paper presents compiler and debugger algorithms that deal with two classes of control flow optimization: merging (such as procedure discovery and cross-jumping) and copying (such as loop unrolling and procedure inlining). Only cross-jumping and procedure inlining are explicitly discussed. The author discusses actual implementation in the Navigator debugger for the Cedar language. (This is a more comprehensive and exhaustive presentation of the Zellweger CSL-83-1 report listed prior to this citation.) Actual algorithms are presented in detail, with informal proofs of correctness and analysis of performance characteristics. Expected behavior (consistent with unoptimized code) is provided in most cases, and high-quality truthful behavior is provided in all others. Primary focus is on these debugger functions: setting breakpoints at program statements, determining the current execution location, and reporting the procedure traceback. Lesser consideration is given to these debugger functions: setting breakpoints at procedure entry and exit, calling procedures from the debugger, single-stepping, and displaying the values of variables. Zurawski, Lawrence W. "Source-Level Debugging of Globally Optimized Code with Expected Behavior." Ph.D. dissertation, University of Illinois at Urbana-Champaign, 1989. [+] This paper presents techniques to maintain (more or less perfect) source fidelity of debugging while maximizing the amount of optimization that can be applied. The main idea is that an optimization algorithm is supplemented with the ability to create a "recovery" function that the debugger uses to preserve the illusion that the optimization has not been performed. Optimizations for which such a recovery function cannot be created are skipped (which includes most code-motion related optimizations, in particular). The approach depends heavily on a language-dependent notion of "inspection points," which in general includes at least all function call sites. The importance of inspection points stems from the fact that recovery functions are provided only at predetermined inspection points and are in principle specific to a particular inspection point. In the extreme case where every point in the program is an inspection point, the benefits of this approach likely approach (degenerate to) being equivalent to compilation without optimization with the associated trivial identity recovery functions. One major advantage of this approach (compared to Hennessy or Zellweger, for example) is that it does provide a means to preserve the ability to change the program state if so desired and at minimum truthfully distinguish variables that can and cannot be validly changed. The discussion includes consideration of continued execution of a program using a parallel unoptimized version of a procedure whose local state has been modified (created either on-the-fly or in advance). Static single assignment form formalism is used to present flow analysis related issues and solution algorithms. |
Legal |