COVID-19 Update: We are currently shipping orders daily. However, due to transit disruptions in some geographies, deliveries may be delayed. To provide all customers with timely access to content, we are offering 50% off Science and Technology Print & eBook bundle options. Terms & conditions.
Why Programs Fail - 1st Edition - ISBN: 9781558608665, 9780080481739

Why Programs Fail

1st Edition

A Guide to Systematic Debugging

Author: Andreas Zeller
Paperback ISBN: 9781558608665
eBook ISBN: 9780080481739
Imprint: Morgan Kaufmann
Published Date: 11th October 2005
Page Count: 480
Sales tax will be calculated at check-out Price includes VAT/GST
Price includes VAT/GST

Institutional Subscription

Secure Checkout

Personal information is secured with SSL technology.

Free Shipping

Free global shipping
No minimum order.


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 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.

Key Features

  • 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.

Table of Contents

About the Author<BR id=""CRLF"">Preface
<BR id=""CRLF"">1 How Failures Come to Be<BR id=""CRLF"">1.1 My Program Does Not Work!<BR id=""CRLF"">1.2 From Defects to Failures<BR id=""CRLF"">1.3 Lost in Time and Space<BR id=""CRLF"">1.4 From Failures to Fixes<BR id=""CRLF"">1.5 Automated Debugging Techniques<BR id=""CRLF"">1.6 Bugs, Faults, or Defects?<BR id=""CRLF"">1.7 Concepts<BR id=""CRLF"">1.8 Tools<BR id=""CRLF"">1.9 Further Reading<BR id=""CRLF"">1.10 Exercises
<BR id=""CRLF"">2 Tracking Problems<BR id=""CRLF"">2.1 Oh! All These Problems<BR id=""CRLF"">2.2 Reporting Problems<BR id=""CRLF"">2.3 Managing Problems<BR id=""CRLF"">2.4 Classifying Problems<BR id=""CRLF"">2.4.1 Severity<BR id=""CRLF"">2.4.2 Priority<BR id=""CRLF"">2.4.3 Identifier<BR id=""CRLF"">2.4.4 Comments<BR id=""CRLF"">2.4.5 Notification<BR id=""CRLF"">2.5 Processing Problems<BR id=""CRLF"">2.6 Managing Problem Tracking<BR id=""CRLF"">2.7 Requirements as Problems<BR id=""CRLF"">2.8 Managing Duplicates<BR id=""CRLF"">2.9 Relating Problems and Fixes<BR id=""CRLF"">2.10 Relating Problems and Tests<BR id=""CRLF"">2.11 Concepts<BR id=""CRLF"">2.12 Tools<BR id=""CRLF"">BUGZILLA<BR id=""CRLF"">PHPBUGTRACKER<BR id=""CRLF"">ISSUETRACKER<BR id=""CRLF"">TRAC<BR id=""CRLF"">SOURCEFORGE<BR id=""CRLF"">GFORGE<BR id=""CRLF"">2.13 Further Reading<BR id=""CRLF"">2.14 Exercises
<BR id=""CRLF"">3 Making Programs Fail<BR id=""CRLF"">3.1 Testing for Debugging<BR id=""CRLF"">3.2 Controlling the Program<BR id=""CRLF"">3.3 Testing at the Presentation Layer<BR id=""CRLF"">3.3.1 Low-level Interaction<BR id=""CRLF"">3.3.2 System-level Interaction<BR id=""CRLF"">3.3.3 Higher-level Interaction<BR id=""CRLF"">3.3.4 Assessing Test Results<BR id=""CRLF"">3.4 Testing at the Functionality Layer<BR id=""CRLF"">3.5 Testing at the Unit Layer<BR id=""CRLF"">3.6 Isolating Units<BR id=""CRLF"">3.7 Designing for Debugging<BR id=""CRLF"">3.8 Preventing Unknown Problems<BR id=""CRLF"">3.9 Concepts<BR id=""CRLF"">3.10 Tools<BR id=""CRLF"">JUNIT<BR id=""CRLF"">ANDROID<BR id=""CRLF"">APPLESCRIPT<BR id=""CRLF"">VBSCRIPT<BR id=""CRLF"">Other scripting languages<BR id=""CRLF"">FAU<BR id=""CRLF"">VMWare<BR id=""CRLF"">Virtual PC<BR id=""CRLF"">3.11 Further Reading<BR id=""CRLF"">3.12 Exercises
<BR id=""CRLF"">4 Reproducing Problems<BR id=""CRLF"">4.1 The First Task in Debugging<BR id=""CRLF"">4.2 Reproducing the Problem Environment<BR id=""CRLF"">4.3 Reproducing Program Execution<BR id=""CRLF"">4.3.1 Reproducing Data<BR id=""CRLF"">4.3.2 Reproducing User Interaction<BR id=""CRLF"">4.3.3 Reproducing Communications<BR id=""CRLF"">4.3.4 Reproducing Time<BR id=""CRLF"">4.3.5 Reproducing Randomness<BR id=""CRLF"">4.3.6 Reproducing Operating Environments<BR id=""CRLF"">4.3.7 Reproducing Schedules<BR id=""CRLF"">4.3.8 Physical Influences<BR id=""CRLF"">4.3.9 Effects of Debugging Tools<BR id=""CRLF"">4.4 Reproducing System Interaction<BR id=""CRLF"">4.5 Focusing on Units<BR id=""CRLF"">4.5.1 Setting Up a Control Layer<BR id=""CRLF"">4.5.2 A Control Example<BR id=""CRLF"">4.5.3 Mock Objects<BR id=""CRLF"">4.5.4 Controlling More Interaction<BR id=""CRLF"">4.6 Concepts<BR id=""CRLF"">4.7 Tools<BR id=""CRLF"">Winrunner<BR id=""CRLF"">Android<BR id=""CRLF"">Revirt<BR id=""CRLF"">Checkpointing Tools<BR id=""CRLF"">4.8 Further Reading<BR id=""CRLF"">4.9 Exercises
<BR id=""CRLF"">5 Simplifying Problems<BR id=""CRLF"">5.1 Simplifying the Problem<BR id=""CRLF"">5.2 The Gecko BugAThon<BR id=""CRLF"">5.3 Manual Simplification<BR id=""CRLF"">5.4 Automatic Simplification<BR id=""CRLF"">5.5 A Simplification Algorithm<BR id=""CRLF"">5.6 Simplifying User Interaction<BR id=""CRLF"">5.7 Random Input Simplified<BR id=""CRLF"">5.8 Simplifying Faster<BR id=""CRLF"">5.8.1 Caching<BR id=""CRLF"">5.8.2 Stop Early<BR id=""CRLF"">5.8.3 Syntactic Simplification<BR id=""CRLF"">5.8.4 Isolate Differences, Not Circumstances<BR id=""CRLF"">5.9 Concepts<BR id=""CRLF"">5.10 Tools<BR id=""CRLF"">Delta Debugging<BR id=""CRLF"">Simplification Library<BR id=""CRLF"">5.11 Further Reading<BR id=""CRLF"">5.12 Exercises
<BR id=""CRLF"">6 Scientific Debugging<BR id=""CRLF"">6.1 How to Become a Debugging Guru<BR id=""CRLF"">6.2 The Scientific Method<BR id=""CRLF"">6.3 Applying the Scientific Method<BR id=""CRLF"">6.3.1 Debugging sample—Preparation<BR id=""CRLF"">6.3.2 Debugging sample—Hypothesis<BR id=""CRLF"">6.3.3 Debugging sample—Hypothesis<BR id=""CRLF"">6.3.4 Debugging sample—Hypothesis<BR id=""CRLF"">6.3.5 Debugging sample—Hypothesis<BR id=""CRLF"">6.4 Explicit Debugging<BR id=""CRLF"">6.5 Keeping a Logbook<BR id=""CRLF"">6.6 Debugging Quick-and-Dirty<BR id=""CRLF"">6.7 Algorithmic Debugging<BR id=""CRLF"">6.8 Deriving a Hypothesis<BR id=""CRLF"">6.9 Reasoning About Programs<BR id=""CRLF"">6.10 Concepts<BR id=""CRLF"">6.11 Further Reading<BR id=""CRLF"">6.12 Exercises
<BR id=""CRLF"">7 Deducing Errors<BR id=""CRLF"">7.1 Isolating Value Origins<BR id=""CRLF"">7.2 Understanding Control Flow<BR id=""CRLF"">7.3 Tracking Dependences<BR id=""CRLF"">7.3.1 Effects of Statements<BR id=""CRLF"">7.3.2 Affected Statements<BR id=""CRLF"">7.3.3 Statement Dependences<BR id=""CRLF"">7.3.4 Following Dependences<BR id=""CRLF"">7.3.5 Leveraging Dependences<BR id=""CRLF"">7.4 Slicing Programs<BR id=""CRLF"">7.4.1 Forward Slices<BR id=""CRLF"">7.4.2 Backward Slices<BR id=""CRLF"">7.4.3 Slice Operations<BR id=""CRLF"">7.4.4 Leveraging Slices<BR id=""CRLF"">7.4.5 Executable Slices<BR id=""CRLF"">7.5 Deducing Code Smells<BR id=""CRLF"">7.6 Limits of Static Analysis<BR id=""CRLF"">7.7 Concepts<BR id=""CRLF"">7.8 Tools<BR id=""CRLF"">CODESURFER<BR id=""CRLF"">FINDBUGS<BR id=""CRLF"">7.9 Further Reading<BR id=""CRLF"">7.10 Exercises
<BR id=""CRLF"">8 Observing Facts<BR id=""CRLF"">8.1 Observing State<BR id=""CRLF"">8.2 Logging Execution<BR id=""CRLF"">8.2.1 Logging Functions<BR id=""CRLF"">8.2.2 Logging Frameworks<BR id=""CRLF"">8.2.3 Logging with Aspects<BR id=""CRLF"">8.2.4 Logging at the Binary Level<BR id=""CRLF"">8.3 Using Debuggers<BR id=""CRLF"">8.3.1 A Debugging Session<BR id=""CRLF"">8.3.2 Controlling Execution<BR id=""CRLF"">8.3.3 Postmortem Debugging<BR id=""CRLF"">8.3.4 Logging Data<BR id=""CRLF"">8.3.5 Invoking Functions<BR id=""CRLF"">8.3.6 Fix and Continue<BR id=""CRLF"">8.3.7 Embedded Debuggers<BR id=""CRLF"">8.3.8 Debugger Caveats<BR id=""CRLF"">8.4 Querying Events<BR id=""CRLF"">8.4.1 Watchpoints<BR id=""CRLF"">8.4.2 Uniform Event Queries<BR id=""CRLF"">8.5 Visualizing State<BR id=""CRLF"">8.6 Concepts<BR id=""CRLF"">8.7 Tools<BR id=""CRLF"">LOG4J<BR id=""CRLF"">ASPECTJ<BR id=""CRLF"">PIN<BR id=""CRLF"">BCEL<BR id=""CRLF"">GDB<BR id=""CRLF"">DDD<BR id=""CRLF"">JAVA SPIDER<BR id=""CRLF"">eDOBS<BR id=""CRLF"">8.8 Further Reading<BR id=""CRLF"">8.9 Exercises
<BR id=""CRLF"">9 Tracking Origins<BR id=""CRLF"">9.1 Reasoning Backwards<BR id=""CRLF"">9.2 Exploring Execution History<BR id=""CRLF"">9.3 Dynamic Slicing<BR id=""CRLF"">9.4 Leveraging Origins<BR id=""CRLF"">9.5 Tracking Down Infections<BR id=""CRLF"">9.6 Concepts<BR id=""CRLF"">9.7 Tools<BR id=""CRLF"">ODB<BR id=""CRLF"">9.8 Further Reading<BR id=""CRLF"">9.9 Exercises
<BR id=""CRLF"">10 Asserting Expectations<BR id=""CRLF"">10.1 Automating Observation<BR id=""CRLF"">10.2 Basic Assertions<BR id=""CRLF"">10.3 Asserting Invariants<BR id=""CRLF"">10.4 Asserting Correctness<BR id=""CRLF"">10.5 Assertions as Specifications<BR id=""CRLF"">10.6 From Assertions to Verification<BR id=""CRLF"">10.7 Reference Runs<BR id=""CRLF"">10.8 System Assertions<BR id=""CRLF"">10.8.1 Validating the Heap with MALLOC_CHECK<BR id=""CRLF"">10.8.2 Avoiding Buffer Overflows with ELECTRICFENCE<BR id=""CRLF"">10.8.3 Detecting Memory Errors with VALGRIND<BR id=""CRLF"">10.8.4 Language Extensions<BR id=""CRLF"">10.9 Checking Production Code<BR id=""CRLF"">10.10 Concepts<BR id=""CRLF"">10.11 Tools<BR id=""CRLF"">JML<BR id=""CRLF"">ESC<BR id=""CRLF"">GUARD<BR id=""CRLF"">VALGRIND<BR id=""CRLF"">PURIFY<BR id=""CRLF"">INSURE++=INSURE++<BR id=""CRLF"">CYCLONE<BR id=""CRLF"">CCURED<BR id=""CRLF"">10.12 Further Reading<BR id=""CRLF"">10.13 Exercises
<BR id=""CRLF"">11 Detecting Anomalies<BR id=""CRLF"">11.1 Capturing Normal Behavior<BR id=""CRLF"">11.2 Comparing Coverage<BR id=""CRLF"">11.3 Statistical Debugging<BR id=""CRLF"">11.4 Collecting Data in the Field<BR id=""CRLF"">11.5 Dynamic Invariants<BR id=""CRLF"">11.6 Invariants on the Fly<BR id=""CRLF"">11.7 From Anomalies to Defects<BR id=""CRLF"">11.8 Concepts<BR id=""CRLF"">11.9 Tools<BR id=""CRLF"">DAIKON<BR id=""CRLF"">DIDUCE<BR id=""CRLF"">11.10 Further Reading<BR id=""CRLF"">11.11 Exercises
<BR id=""CRLF"">12 Causes and Effects<BR id=""CRLF"">12.1 Causes and Alternate Worlds<BR id=""CRLF"">12.2 Verifying Causes<BR id=""CRLF"">12.3 Causality in Practice<BR id=""CRLF"">12.4 Finding Actual Causes<BR id=""CRLF"">12.5 Narrowing Down Causes<BR id=""CRLF"">12.6 A Narrowing Example<BR id=""CRLF"">12.7 The Common Context<BR id=""CRLF"">12.8 Causes in Debugging<BR id=""CRLF"">12.9 Concepts<BR id=""CRLF"">12.10 Further Reading<BR id=""CRLF"">12.11 Exercises
<BR id=""CRLF"">13 Isolating Failure Causes<BR id=""CRLF"">13.1 Isolating Causes Automatically<BR id=""CRLF"">13.2 Isolating versus Simplifying<BR id=""CRLF"">13.3 An Isolation Algorithm<BR id=""CRLF"">13.4 Implementing Isolation<BR id=""CRLF"">13.5 Isolating Failure-inducing Input<BR id=""CRLF"">13.6 Isolating Failure-inducing Schedules<BR id=""CRLF"">13.7 Isolating Failure-inducing Changes<BR id=""CRLF"">13.8 Problems and Limitations<BR id=""CRLF"">13.9 Concepts<BR id=""CRLF"">13.10 Tools<BR id=""CRLF"">Delta Debugging Plug-ins for ECLIPSE<BR id=""CRLF"">CCACHE<BR id=""CRLF"">13.11 Further Reading<BR id=""CRLF"">13.12 Exercises
<BR id=""CRLF"">14 Isolating Cause-Effect Chains<BR id=""CRLF"">14.1 Useless Causes<BR id=""CRLF"">14.2 Capturing Program States<BR id=""CRLF"">14.3 Comparing Program States<BR id=""CRLF"">14.4 Isolating Relevant Program States<BR id=""CRLF"">14.5 Isolating Cause-Effect Chains<BR id=""CRLF"">14.6 Isolating Failure-inducing Code<BR id=""CRLF"">14.7 Issues and Risks<BR id=""CRLF"">14.8 Concepts<BR id=""CRLF"">14.9 Tools<BR id=""CRLF"">ASKIGOR<BR id=""CRLF"">IGOR<BR id=""CRLF"">14.10 Further Reading<BR id=""CRLF"">14.11 Exercises
<BR id=""CRLF"">15 Fixing the Defect<BR id=""CRLF"">15.1 Locating the Defect<BR id=""CRLF"">15.2 Focusing on the Most Likely Errors<BR id=""CRLF"">15.3 Validating the Defect<BR id=""CRLF"">15.3.1 Does the Error Cause the Failure?<BR id=""CRLF"">15.3.2 Is the Cause Really an Error?<BR id=""CRLF"">15.3.3 Think Before You Code<BR id=""CRLF"">The Devil’s Guide to Debugging<BR id=""CRLF"">15.4 Correcting the Defect<BR id=""CRLF"">15.4.1 Does the Failure No Longer Occur?<BR id=""CRLF"">15.4.2 Did the Correction Introduce New Problems?<BR id=""CRLF"">15.4.3 Was the Same Mistake Made Elsewhere?<BR id=""CRLF"">15.4.4 Did I Do My Homework?<BR id=""CRLF"">15.5 Workarounds<BR id=""CRLF"">15.6 Learning from Mistakes<BR id=""CRLF"">15.7 Concepts<BR id=""CRLF"">15.8 Further Reading<BR id=""CRLF"">15.9 Exercises
<BR id=""CRLF"">Appendix: Formal Definitions<BR id=""CRLF"">A.1 Delta Debugging<BR id=""CRLF"">A.1.1 Configurations<BR id=""CRLF"">A.2 Passing and Failing Run<BR id=""CRLF"">A.3 Tests<BR id=""CRLF"">A.4 Minimality<BR id=""CRLF"">A.5 Simplifying<BR id=""CRLF"">A.6 Differences<BR id=""CRLF"">A.7 Isolating<BR id=""CRLF"">A.2 Memory Graphs<BR id=""CRLF"">A.2.1 Formal Structure<BR id=""CRLF"">A.2.2 Unfolding Data Structures<BR id=""CRLF"">A.2.3 Matching Vertices and Edges<BR id=""CRLF"">A.2.4 Computing the Common Subgraph<BR id=""CRLF"">A.2.5 Computing Graph Differences<BR id=""CRLF"">A.2.6 Applying Partial State Changes<BR id=""CRLF"">A.2.7 Capturing C State<BR id=""CRLF"">A.3 Cause-Effect Chains
<BR id=""CRLF"">Glossary<BR id=""CRLF"">Bibliography<BR id=""CRLF"">Index


No. of pages:
© Morgan Kaufmann 2006
11th October 2005
Morgan Kaufmann
Paperback ISBN:
eBook ISBN:

About the Author

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, Germany


“James Madison wrote: ‘If men were angels, no government would be necessary.’ If he lived today, Madison might have written: ‘If software developers were angels, debugging would be unnecessary.’ Most of us, however, make mistakes, and many of us even make errors while designing and writing software. Our mistakes need to be found and fixed, an activity called debugging that originated with the first computer programs. Today every computer program written is also debugged, but debugging is not a widely studied or taught skill. Few books, beyond this one, present a systematic approach to finding and fixing programming errors.” —from the foreword by James Larus, Microsoft Research "Andreas Zeller seeks to equip you with a comprehensive arsenal of techniques and the appropriate mind-sets for employing them." Rick Wayne, Software Development, January 2006

Ratings and Reviews