目录 前言 v 致谢 x 作者简介 xiv Figures xix Listings xx Item 11: Minimize the Turnaround Time from Your Changes to Their Result 28 Item 12: Automate Complex Testing Scenarios 29 Item 13: Enable a Comprehensive Overview of Your Debugging Data 32 Item 14: Consider Updating Your Software 33 Item 15: Consult Third-Party Source Code for Insights on Its Use 34 Item 16: Use Specialized Monitoring and Test Equipment 36 Item 17: Increase the Prominence of a Failure’s Effects 40 Item 18: Enable the Debugging of Unwieldy Systems from Your Desk 42 Item 19: Automate Debugging Tasks 44 Item 20: Houseclean Before and After Debugging 45 Item 21: Fix All Instances of a Problem Class 46 Chapter 3: General-Purpose Tools and Techniques 49 Item 22: Analyze Debug Data with Unix Command-Line Tools 49 Item 23: Utilize Command-Line Tool Options and Idioms 55 Item 24: Explore Debug Data with Your Editor 57 Item 25: Optimize Your Work Environment 59 Item 26: Hunt the Causes and History of Bugs with the Revision Control System 64 Item 27: Use Monitoring Tools on Systems Composed of Independent Processes 67 Chapter 4: Debugger Techniques 71 Item 28: Use Code Compiled for Symbolic Debugging 71 Item 29: Step through the Code 76 Item 30: Use Code and Data Breakpoints 77 Item 31: Familiarize Yourself with Reverse Debugging 80 Item 32: Navigate along the Calls between Routines 82 Item 33: Look for Errors by Examining the Values of Variables and Expressions 84 Item 34: Know How to Attach a Debugger to a Running Process 87 Item 35: Know How to Work with Core Dumps 89 Item 36: Tune Your Debugging Tools 92 Item 37: Know How to View Assembly Code and Raw Memory 95 Chapter 5: Programming Techniques 101 Item 38: Review and Manually Execute Suspect Code 101 Item 39: Go Over Your Code and Reasoning with a Colleague 103 Item 40: Add Debugging Functionality 104 Item 41: Add Logging Statements 108 Item 42: Use Unit Tests 112 Item 43: Use Assertions 116 Item 44: Verify Your Reasoning by Perturbing the Debugged Program 119 Item 45: Minimize the Differences between a Working Example and the Failing Code 120 Item 46: Simplify the Suspect Code 121 Item 47: Consider Rewriting the Suspect Code in Another Language 124 Item 48: Improve the Suspect Code’s Readability and Structure 126 Item 49: Fix the Bug’s Cause, Rather Than Its Symptom 129 Chapter 6: Compile-Time Techniques 133 Item 50: Examine Generated Code 133 Item 51: Use Static Program Analysis 136 Item 52: Configure Deterministic Builds and Executions 141 Item 53: Configure the Use of Debugging Libraries and Checks 143 Chapter 7: Runtime Techniques 149 Item 54: Find the Fault by Constructing a Test Case 149 Item 55: Fail Fast 153 Item 56: Examine Application Log Files 154 Item 57: Profile the Operation of Systems and Processes 158 Item 58: Trace the Code’s Execution 162 Item 59: Use Dynamic Program Analysis Tools 168 Chapter 8: Debugging Multi-threaded Code 171 Item 60: Analyze Deadlocks with Postmortem Debugging 171 Item 61: Capture and Replicate 178 Item 62: Uncover Deadlocks and Race Conditions with Specialized Tools 183 Item 63: Isolate and Remove Nondeterminism 188 Item 64: Investigate Scalability Issues by Looking at Contention 190 Item 65: Locate False Sharing by Using Performance Counters 193 Item 66: Consider Rewriting the Code Using Higher-Level Abstractions 197 Web Resources 207 Index 211