
Why Programs Fail
A Guide to Systematic Debugging
- 1st Edition - October 11, 2005
- Imprint: Morgan Kaufmann
- Author: Andreas Zeller
- Language: English
- eBook ISBN:9 7 8 - 0 - 0 8 - 0 4 8 1 7 3 - 9
Why Programs Fail is about bugs in computer programs, how to find them, how to reproduce them, and how to fix them in such a way that they do not occur anymore. This is the first… Read more

Purchase options

Institutional subscription on ScienceDirect
Request a sales quoteWhy Programs Fail is about bugs in computer programs, how to find them, how to reproduce them, and how to fix them in such a way that they do not occur anymore. This is the first comprehensive book on systematic debugging and covers a wide range of tools and techniques ranging from hands-on observation to fully automated diagnoses, and includes instructions for building automated debuggers. This discussion is built upon a solid theory of how failures occur, rather than relying on seat-of-the-pants techniques, which are of little help with large software systems or to those learning to program. The author, Andreas Zeller, is well known in the programming community for creating the GNU Data Display Debugger (DDD), a tool that visualizes the data structures of a program while it is running.
- Winner of a 2006 Jolt Productivity Award for Technical Books
- Shows how to reproduce software failures faithfully, how to isolate what is important about the failure, and to discover what caused it
- Describes how to fix the program in the best possible way, and shows how to create your own automated debugging tools
- Includes exercises and extensive references for further study
Software developers.
About the AuthorPreface1 How Failures Come to Be1.1 My Program Does Not Work!1.2 From Defects to Failures1.3 Lost in Time and Space1.4 From Failures to Fixes1.5 Automated Debugging Techniques1.6 Bugs, Faults, or Defects?1.7 Concepts1.8 Tools1.9 Further Reading1.10 Exercises2 Tracking Problems2.1 Oh! All These Problems2.2 Reporting Problems2.3 Managing Problems2.4 Classifying Problems2.4.1 Severity2.4.2 Priority2.4.3 Identifier2.4.4 Comments2.4.5 Notification2.5 Processing Problems2.6 Managing Problem Tracking2.7 Requirements as Problems2.8 Managing Duplicates2.9 Relating Problems and Fixes2.10 Relating Problems and Tests2.11 Concepts2.12 ToolsBUGZILLAPHPBUGTRACKERISSUETRACKERTRACSOURCEFORGEGFORGE2.13 Further Reading2.14 Exercises3 Making Programs Fail3.1 Testing for Debugging3.2 Controlling the Program3.3 Testing at the Presentation Layer3.3.1 Low-level Interaction3.3.2 System-level Interaction3.3.3 Higher-level Interaction3.3.4 Assessing Test Results3.4 Testing at the Functionality Layer3.5 Testing at the Unit Layer3.6 Isolating Units3.7 Designing for Debugging3.8 Preventing Unknown Problems3.9 Concepts3.10 ToolsJUNITANDROIDAPPLESCRIPTVBSCRIPTOther scripting languagesFAUVMWareVirtual PC3.11 Further Reading3.12 Exercises4 Reproducing Problems4.1 The First Task in Debugging4.2 Reproducing the Problem Environment4.3 Reproducing Program Execution4.3.1 Reproducing Data4.3.2 Reproducing User Interaction4.3.3 Reproducing Communications4.3.4 Reproducing Time4.3.5 Reproducing Randomness4.3.6 Reproducing Operating Environments4.3.7 Reproducing Schedules4.3.8 Physical Influences4.3.9 Effects of Debugging Tools4.4 Reproducing System Interaction4.5 Focusing on Units4.5.1 Setting Up a Control Layer4.5.2 A Control Example4.5.3 Mock Objects4.5.4 Controlling More Interaction4.6 Concepts4.7 ToolsWinrunnerAndroidRevirtCheckpointing Tools4.8 Further Reading4.9 Exercises5 Simplifying Problems5.1 Simplifying the Problem5.2 The Gecko BugAThon5.3 Manual Simplification5.4 Automatic Simplification5.5 A Simplification Algorithm5.6 Simplifying User Interaction5.7 Random Input Simplified5.8 Simplifying Faster5.8.1 Caching5.8.2 Stop Early5.8.3 Syntactic Simplification5.8.4 Isolate Differences, Not Circumstances5.9 Concepts5.10 ToolsDelta DebuggingSimplification Library5.11 Further Reading5.12 Exercises6 Scientific Debugging6.1 How to Become a Debugging Guru6.2 The Scientific Method6.3 Applying the Scientific Method6.3.1 Debugging sample—Preparation6.3.2 Debugging sample—Hypothesis6.3.3 Debugging sample—Hypothesis6.3.4 Debugging sample—Hypothesis6.3.5 Debugging sample—Hypothesis6.4 Explicit Debugging6.5 Keeping a Logbook6.6 Debugging Quick-and-Dirty6.7 Algorithmic Debugging6.8 Deriving a Hypothesis6.9 Reasoning About Programs6.10 Concepts6.11 Further Reading6.12 Exercises7 Deducing Errors7.1 Isolating Value Origins7.2 Understanding Control Flow7.3 Tracking Dependences7.3.1 Effects of Statements7.3.2 Affected Statements7.3.3 Statement Dependences7.3.4 Following Dependences7.3.5 Leveraging Dependences7.4 Slicing Programs7.4.1 Forward Slices7.4.2 Backward Slices7.4.3 Slice Operations7.4.4 Leveraging Slices7.4.5 Executable Slices7.5 Deducing Code Smells7.6 Limits of Static Analysis7.7 Concepts7.8 ToolsCODESURFERFINDBUGS7.9 Further Reading7.10 Exercises8 Observing Facts8.1 Observing State8.2 Logging Execution8.2.1 Logging Functions8.2.2 Logging Frameworks8.2.3 Logging with Aspects8.2.4 Logging at the Binary Level8.3 Using Debuggers8.3.1 A Debugging Session8.3.2 Controlling Execution8.3.3 Postmortem Debugging8.3.4 Logging Data8.3.5 Invoking Functions8.3.6 Fix and Continue8.3.7 Embedded Debuggers8.3.8 Debugger Caveats8.4 Querying Events8.4.1 Watchpoints8.4.2 Uniform Event Queries8.5 Visualizing State8.6 Concepts8.7 ToolsLOG4JASPECTJPINBCELGDBDDDJAVA SPIDEReDOBS8.8 Further Reading8.9 Exercises9 Tracking Origins9.1 Reasoning Backwards9.2 Exploring Execution History9.3 Dynamic Slicing9.4 Leveraging Origins9.5 Tracking Down Infections9.6 Concepts9.7 ToolsODB9.8 Further Reading9.9 Exercises10 Asserting Expectations10.1 Automating Observation10.2 Basic Assertions10.3 Asserting Invariants10.4 Asserting Correctness10.5 Assertions as Specifications10.6 From Assertions to Verification10.7 Reference Runs10.8 System Assertions10.8.1 Validating the Heap with MALLOC_CHECK10.8.2 Avoiding Buffer Overflows with ELECTRICFENCE10.8.3 Detecting Memory Errors with VALGRIND10.8.4 Language Extensions10.9 Checking Production Code10.10 Concepts10.11 ToolsJMLESCGUARDVALGRINDPURIFYINSURE++=INSURE++CYCLONECCURED10.12 Further Reading10.13 Exercises11 Detecting Anomalies11.1 Capturing Normal Behavior11.2 Comparing Coverage11.3 Statistical Debugging11.4 Collecting Data in the Field11.5 Dynamic Invariants11.6 Invariants on the Fly11.7 From Anomalies to Defects11.8 Concepts11.9 ToolsDAIKONDIDUCE11.10 Further Reading11.11 Exercises12 Causes and Effects12.1 Causes and Alternate Worlds12.2 Verifying Causes12.3 Causality in Practice12.4 Finding Actual Causes12.5 Narrowing Down Causes12.6 A Narrowing Example12.7 The Common Context12.8 Causes in Debugging12.9 Concepts12.10 Further Reading12.11 Exercises13 Isolating Failure Causes13.1 Isolating Causes Automatically13.2 Isolating versus Simplifying13.3 An Isolation Algorithm13.4 Implementing Isolation13.5 Isolating Failure-inducing Input13.6 Isolating Failure-inducing Schedules13.7 Isolating Failure-inducing Changes13.8 Problems and Limitations13.9 Concepts13.10 ToolsDelta Debugging Plug-ins for ECLIPSECCACHE13.11 Further Reading13.12 Exercises14 Isolating Cause-Effect Chains14.1 Useless Causes14.2 Capturing Program States14.3 Comparing Program States14.4 Isolating Relevant Program States14.5 Isolating Cause-Effect Chains14.6 Isolating Failure-inducing Code14.7 Issues and Risks14.8 Concepts14.9 ToolsASKIGORIGOR14.10 Further Reading14.11 Exercises15 Fixing the Defect15.1 Locating the Defect15.2 Focusing on the Most Likely Errors15.3 Validating the Defect15.3.1 Does the Error Cause the Failure?15.3.2 Is the Cause Really an Error?15.3.3 Think Before You CodeThe Devil’s Guide to Debugging15.4 Correcting the Defect15.4.1 Does the Failure No Longer Occur?15.4.2 Did the Correction Introduce New Problems?15.4.3 Was the Same Mistake Made Elsewhere?15.4.4 Did I Do My Homework?15.5 Workarounds15.6 Learning from Mistakes15.7 Concepts15.8 Further Reading15.9 ExercisesAppendix: Formal DefinitionsA.1 Delta DebuggingA.1.1 ConfigurationsA.2 Passing and Failing RunA.3 TestsA.4 MinimalityA.5 SimplifyingA.6 DifferencesA.7 IsolatingA.2 Memory GraphsA.2.1 Formal StructureA.2.2 Unfolding Data StructuresA.2.3 Matching Vertices and EdgesA.2.4 Computing the Common SubgraphA.2.5 Computing Graph DifferencesA.2.6 Applying Partial State ChangesA.2.7 Capturing C StateA.3 Cause-Effect ChainsGlossaryBibliographyIndex
- Edition: 1
- Published: October 11, 2005
- Imprint: Morgan Kaufmann
- No. of pages: 480
- Language: English
- eBook ISBN: 9780080481739
AZ
Andreas Zeller
Andreas Zeller is a full professor for Software Engineering at Saarland University in Saarbruecken, Germany. His research concerns the analysis of large software systems and their development process; his students are funded by companies like Google, Microsoft, or SAP. In 2010, Zeller was inducted as Fellow of the ACM for his contributions to automated debugging and mining software archives. In 2011, he received an ERC Advanced Grant, Europe's highest and most prestigious individual research grant, for work on specification mining and test case generation. His book "Why programs fail", the "standard reference on debugging", obtained the 2006 Software Development Jolt Productivity Award.
Affiliations and expertise
Saarland University, Saarbruecken, GermanyRead Why Programs Fail on ScienceDirect