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.
Suitable for any programming language and all levels of programming experience
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, and a companion Web site with source code for all examples and additional debugging resources
Review By: Arnoud Buzing 06/15/2010"Why Programs Fail" is divided into three major parts stretched over fifteen chapters. The first five chapters are introductory and discuss the origin of failures, how to track failures reported by users, how to make programs fail by devising tests, and how to reproduce and simplify problems. The first chapter precisely defines the concepts “defect,” “infection,” and “failure,” where defect is a fault located in the code, an infection is a program state during execution, and failure is the error observed by a user. For the purposes of the book, testing (or debugging) is defined as the activity of demonstrating, reproducing, and simplifying a known problem (as opposed to uncovering unknown problems).
Having defined the basic concepts, the next six chapters go into the details of debugging. This second part of the book starts out by introducing the scientific method to debugging: Hypotheses about a defect are iteratively refined after predicted outcomes of experiments fail to match the observed behavior, until finally a hypothesis holds that can no longer be rejected. The subsequent chapters detail the tools and techniques that can be used to reject and refine hypotheses. In particular they discuss the use of debuggers to observe a program's state and the use of assertions to check pre-conditions, invariants, and post-conditions.
The final four chapters of the book focus on finding possible causes, isolating the correct causes, and eventually isolating the cause-effect chain from defect to failure. The last chapter discusses fixing the defect correctly rather than simply patching it to fix one observed failure but introducing multiple new ones. The appendix gives a list of formal definitions of the concepts used in the book.
With “Why Programs Fail,” Andreas Zeller has written a most wonderful text on the topic of systematic debugging. The flow of the text takes you logically from one step to the next, starting with observing a failure and systematically working its way back to isolating the defect and fixing it correctly.
The only chapter that stands out is chapter two, "Tracking Problems," which is a bit of obligatory exposition on bugs-database systems. The book is typeset very well, which helps with readability; there are no long multipage sidebars to interrupt the flow of the main text. Every chapter ends with a concept summary, a list of available tools, further reading, and exercises, making this a useful teaching text. A small number of brief anecdotes help to lighten the text as well.
I particularly appreciated Zeller’s restraint from dedicating an entire chapter or two to give a mini DDD tutorial. He discusses all software tools are objectively and doesn't use the book as a vehicle to promote DDD. This is a classic book that I will place on a shelf near my desk as a reference.
Review By: Kevin Dahlhausen 06/15/2010The fact that Andreas Zeller, author of this book, created the GNU Data Display Debugger set high expectations for this book. I was not disappointed. Andreas's goal for this book is to open the eyes of developers to the benefits of using a systematic approach to debugging. Being a developer for over fifteen years, I was pleasantly surprised with the advances in debugging that Andreas present in this book.
The chapters are well-structured. Each consists of an introduction, the core material, a summary list of the main concepts that includes short "how-to" steps, a section on software tools that address the concepts in the chapter, links to additional reading on the topic, and a set of exercises. Some chapters contain case studies that illustrate the chapter’s main point(s). The format works very well for this material.
In Why Programs Fail, Andreas starts by laying the groundwork for a formal debugging process. He does this by describing the origins of defects while introducing formal definitions. He then covers techniques that isolate the problem and distill it down to the minimum scope that still demonstrates the problem. Then Andreas teaches the scientific method as applied to debugging and introduces the concept of delta-debugging. Finally he discusses formal techniques to use when fixing the defect. The techniques presented in this book are not language specific.
This book is intended for any programmer that is familiar with programming and manual debugging. Mid-level to advanced developers will benefit most from this book. Novices will have difficulty digesting and relating the material to their work. The field of automating debugging is new enough that even advanced developers will find a wealth of information in this book. They should not be bored.
I've always felt that one of the best things my engineering education has given me is a scientific approach to problem solving. The great benefit of this book is that it uses the scientific method to create a formal discipline for debugging. This discipline can be automated in ways that were not thought of until recently. One example of this is the DDCHANGE plug-in for Eclipse that automatically identifies which of multiple code changes has introduced a given bug.
Andreas' style of writing is quite enjoyable. He maintains the correct balance of casualness and formality even when discussing formal definitions and derivations. If I were to rewrite this book, the only thing I would change is the second chapter on defect tracking. It could easily be left out. This topic is covered in many other texts unlike the rest of the material in this book. I would rather see the space devoted to more information or case studies on advanced debugging. Formal defect tracking does lay the groundwork for effective debugging, so this chapter is not out of place, it just does not bring new information to the reader to the extent that the rest of the book does.
Any programmer reading this book will benefit from exposure to this material no matter how far he or she ventures into automated debugging. It's emphasis on the scientific method as applied to debugging alone will provide handsome dividends to the reader.