Why Programs Fail - 1st Edition - ISBN: 9781558608665, 9780080481739

Why Programs Fail

1st Edition

A Guide to Systematic Debugging

Authors: Andreas Zeller
eBook ISBN: 9780080481739
Paperback ISBN: 9781558608665
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
× Read this ebook on your PC, Mac, Apple iOS and Andriod mobile devices and eReader

This ebook is protected by Adobe Content Server digital rights management.

For more information on how to use .acsm files please click the Ebook Format Help link.

Institutional Access

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

1 How Failures Come to Be
1.1 My Program Does Not Work!
1.2 From Defects to Failures
1.3 Lost in Time and Space
1.4 From Failures to Fixes
1.5 Automated Debugging Techniques
1.6 Bugs, Faults, or Defects?
1.7 Concepts
1.8 Tools
1.9 Further Reading
1.10 Exercises

2 Tracking Problems
2.1 Oh! All These Problems
2.2 Reporting Problems
2.3 Managing Problems
2.4 Classifying Problems
2.4.1 Severity
2.4.2 Priority
2.4.3 Identifier
2.4.5 Notification
2.5 Processing Problems
2.6 Managing Problem Tracking
2.7 Requirements as Problems
2.8 Managing Duplicates
2.9 Relating Problems and Fixes
2.10 Relating Problems and Tests
2.11 Concepts
2.12 Tools
2.13 Further Reading
2.14 Exercises

3 Making Programs Fail
3.1 Testing for Debugging
3.2 Controlling the Program
3.3 Testing at the Presentation Layer
3.3.1 Low-level Interaction
3.3.2 System-level Interaction
3.3.3 Higher-level Interaction
3.3.4 Assessing Test Results
3.4 Testing at the Functionality Layer
3.5 Testing at the Unit Layer
3.6 Isolating Units
3.7 Designing for Debugging
3.8 Preventing Unknown Problems
3.9 Concepts
3.10 Tools
Other scripting languages
Virtual PC
3.11 Further Reading
3.12 Exercises

4 Reproducing Problems
4.1 The First Task in Debugging
4.2 Reproducing the Problem Environment
4.3 Reproducing Program Execution
4.3.1 Reproducing Data
4.3.2 Reproducing User Interaction
4.3.3 Reproducing Communications
4.3.4 Reproducing Time
4.3.5 Reproducing Randomness
4.3.6 Reproducing Operating Environments
4.3.7 Reproducing Schedules
4.3.8 Physical Influences
4.3.9 Effects of Debugging Tools
4.4 Reproducing System Interaction
4.5 Focusing on Units
4.5.1 Setting Up a Control Layer
4.5.2 A Control Example
4.5.3 Mock Objects
4.5.4 Controlling More Interaction
4.6 Concepts
4.7 Tools
Checkpointing Tools
4.8 Further Reading
4.9 Exercises

5 Simplifying Problems
5.1 Simplifying the Problem
5.2 The Gecko BugAThon
5.3 Manual Simplification
5.4 Automatic Simplification
5.5 A Simplification Algorithm
5.6 Simplifying User Interaction
5.7 Random Input Simplified
5.8 Simplifying Faster
5.8.1 Caching
5.8.2 Stop Early
5.8.3 Syntactic Simplification
5.8.4 Isolate Differences, Not Circumstances
5.9 Concepts
5.10 Tools
Delta Debugging
Simplification Library
5.11 Further Reading
5.12 Exercises

6 Scientific Debugging
6.1 How to Become a Debugging Guru
6.2 The Scientific Method
6.3 Applying the Scientific Method
6.3.1 Debugging sample—Preparation
6.3.2 Debugging sample—Hypothesis
6.3.3 Debugging sample—Hypothesis
6.3.4 Debugging sample—Hypothesis
6.3.5 Debugging sample—Hypothesis
6.4 Explicit Debugging
6.5 Keeping a Logbook
6.6 Debugging Quick-and-Dirty
6.7 Algorithmic Debugging
6.8 Deriving a Hypothesis
6.9 Reasoning About Programs
6.10 Concepts
6.11 Further Reading
6.12 Exercises

7 Deducing Errors
7.1 Isolating Value Origins
7.2 Understanding Control Flow
7.3 Tracking Dependences
7.3.1 Effects of Statements
7.3.2 Affected Statements
7.3.3 Statement Dependences
7.3.4 Following Dependences
7.3.5 Leveraging Dependences
7.4 Slicing Programs
7.4.1 Forward Slices
7.4.2 Backward Slices
7.4.3 Slice Operations
7.4.4 Leveraging Slices
7.4.5 Executable Slices
7.5 Deducing Code Smells
7.6 Limits of Static Analysis
7.7 Concepts
7.8 Tools
7.9 Further Reading
7.10 Exercises

8 Observing Facts
8.1 Observing State
8.2 Logging Execution
8.2.1 Logging Functions
8.2.2 Logging Frameworks
8.2.3 Logging with Aspects
8.2.4 Logging at the Binary Level
8.3 Using Debuggers
8.3.1 A Debugging Session
8.3.2 Controlling Execution
8.3.3 Postmortem Debugging
8.3.4 Logging Data
8.3.5 Invoking Functions
8.3.6 Fix and Continue
8.3.7 Embedded Debuggers
8.3.8 Debugger Caveats
8.4 Querying Events
8.4.1 Watchpoints
8.4.2 Uniform Event Queries
8.5 Visualizing State
8.6 Concepts
8.7 Tools
8.8 Further Reading
8.9 Exercises

9 Tracking Origins
9.1 Reasoning Backwards
9.2 Exploring Execution History
9.3 Dynamic Slicing
9.4 Leveraging Origins
9.5 Tracking Down Infections
9.6 Concepts
9.7 Tools
9.8 Further Reading
9.9 Exercises

10 Asserting Expectations
10.1 Automating Observation
10.2 Basic Assertions
10.3 Asserting Invariants
10.4 Asserting Correctness
10.5 Assertions as Specifications
10.6 From Assertions to Verification
10.7 Reference Runs
10.8 System Assertions
10.8.1 Validating the Heap with MALLOC_CHECK
10.8.2 Avoiding Buffer Overflows with ELECTRICFENCE
10.8.3 Detecting Memory Errors with VALGRIND
10.8.4 Language Extensions
10.9 Checking Production Code
10.10 Concepts
10.11 Tools
10.12 Further Reading
10.13 Exercises

11 Detecting Anomalies
11.1 Capturing Normal Behavior
11.2 Comparing Coverage
11.3 Statistical Debugging
11.4 Collecting Data in the Field
11.5 Dynamic Invariants
11.6 Invariants on the Fly
11.7 From Anomalies to Defects
11.8 Concepts
11.9 Tools
11.10 Further Reading
11.11 Exercises

12 Causes and Effects
12.1 Causes and Alternate Worlds
12.2 Verifying Causes
12.3 Causality in Practice
12.4 Finding Actual Causes
12.5 Narrowing Down Causes
12.6 A Narrowing Example
12.7 The Common Context
12.8 Causes in Debugging
12.9 Concepts
12.10 Further Reading
12.11 Exercises

13 Isolating Failure Causes
13.1 Isolating Causes Automatically
13.2 Isolating versus Simplifying
13.3 An Isolation Algorithm
13.4 Implementing Isolation
13.5 Isolating Failure-inducing Input
13.6 Isolating Failure-inducing Schedules
13.7 Isolating Failure-inducing Changes
13.8 Problems and Limitations
13.9 Concepts
13.10 Tools
Delta Debugging Plug-ins for ECLIPSE
13.11 Further Reading
13.12 Exercises

14 Isolating Cause-Effect Chains
14.1 Useless Causes
14.2 Capturing Program States
14.3 Comparing Program States
14.4 Isolating Relevant Program States
14.5 Isolating Cause-Effect Chains
14.6 Isolating Failure-inducing Code
14.7 Issues and Risks
14.8 Concepts
14.9 Tools
14.10 Further Reading
14.11 Exercises

15 Fixing the Defect
15.1 Locating the Defect
15.2 Focusing on the Most Likely Errors
15.3 Validating the Defect
15.3.1 Does the Error Cause the Failure?
15.3.2 Is the Cause Really an Error?
15.3.3 Think Before You Code
The Devil’s Guide to Debugging
15.4 Correcting the Defect
15.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 Workarounds
15.6 Learning from Mistakes
15.7 Concepts
15.8 Further Reading
15.9 Exercises

Appendix: Formal Definitions
A.1 Delta Debugging
A.1.1 Configurations
A.2 Passing and Failing Run
A.3 Tests
A.4 Minimality
A.5 Simplifying
A.6 Differences
A.7 Isolating
A.2 Memory Graphs
A.2.1 Formal Structure
A.2.2 Unfolding Data Structures
A.2.3 Matching Vertices and Edges
A.2.4 Computing the Common Subgraph
A.2.5 Computing Graph Differences
A.2.6 Applying Partial State Changes
A.2.7 Capturing C State
A.3 Cause-Effect Chains



No. of pages:
© Morgan Kaufmann 2006
Morgan Kaufmann
eBook ISBN:
Paperback 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