introduction to debugging
play

Introduction to Debugging Software Engineering Andreas Zeller - PDF document

Introduction to Debugging Software Engineering Andreas Zeller Saarland University 1 The Problem 2 2 Facts on Debugging Software bugs cost ~60 bln US$/yr in US Improvements could reduce cost by 30% Validation (including


  1. Introduction to Debugging Software Engineering Andreas Zeller • Saarland University 1 The Problem 2 2 Facts on Debugging • Software bugs cost ~60 bln US$/yr in US • Improvements could reduce cost by 30% • Validation (including debugging) can easily take up to 50-75% of the development time • When debugging, some people are three times as efficient than others 3

  2. 4 How to Debug (Sommerville 2004) Design Repair Re-test Locate error error repair error program 5 The Process T rack the problem R eproduce A utomate F ind Origins F ocus I solate C orrect 6

  3. T R Tracking Problems A F F I C 7 T R Tracking Problems A F F I C • Every problem gets entered into a problem database • The priority determines which problem is handled next • The product is ready when all problems are resolved 8 T R Problem Life Cycle A F F I C INVALID Status DUPLICATE NEW FIXED Resulting Resolution INVALID DUPLICATE FIXED UNCONFIRMED NEW ASSIGNED RESOLVED VERIFIED CLOSED WONTFIX if resolution is FIXED WORKSFORME REOPENED 9

  4. T R Reproduce A F F I C Randomness Operating System Communication Concurrency Program Physics Interaction Debugger Data 10 T R Automate A F F I // Test for host C public void testHost() { int noPort = -1; assertEquals(askigor_url.getHost(), "www.askigor.org"); assertEquals(askigor_url.getPort(), noPort); } // Test for path public void testPath() { assertEquals(askigor_url.getPath(), "/status.php"); } // Test for query part public void testQuery() { assertEquals(askigor_url.getQuery(), "id=sample"); } 11 T R Automate A F F I C • Every problem should be reproducible automatically • Achieved via appropriate (unit) tests • After each change, we re-run the tests 12

  5. T R Finding Origins A F F I C 1. The programmer creates Variables a defect in the code. ✘ 2. When executed, the ✘ defect creates an infection . 3. The infection propagates . 4. The infection causes a ✘ ✘ failure . This infection chain must be traced ✘ t back – and broken. Not every defect creates an infection – not every infection results in a failure 13 T R Finding Origins A F F I Variables C ✔ ? ✘ t t 14 T R The Defect A F F I Variables C ✔ ✘ ✘ t t 15

  6. T R A Program State A F F I C 16 T R A F F I C 17 T R Finding Origins A F F I C Variables 1. We start with a ✘ known infection ✘ (say, at the failure) 2. We search the infection in the previous state ✘ ✘ ✘ t 18

  7. T R A F F I C 19 T R A Program State A F F I C 20 T T R R Search A A F F F F I I C C 21

  8. 22 T R Focus A F F I C During our search for infection, we focus upon locations that • are possibly wrong (e.g., because they were buggy before) • are explicitly wrong (e.g., because they violate an assertion ) Assertions are the best way to find infections! 23 T R Finding Infections A F F I C class Time { public: int hour(); // 0..23 int minutes(); // 0..59 int seconds(); // 0..60 (incl. leap seconds) void set_hour(int h); … } Every time between 00:00:00 and 23:59:60 is valid 24

  9. T R Finding Origins A F F I bool Time::sane() C { return (0 <= hour() && hour() <= 23) && (0 <= minutes() && minutes() <= 59) && (0 <= seconds() && seconds() <= 60); } void Time::set_hour(int h) { assert (sane()); // Precondition … assert (sane()); // Postcondition } 25 T R Finding Origins A F F I bool Time::sane() bool Time::sane() C { { return (0 <= hour() && hour() <= 23) && return (0 <= hour() && hour() <= 23) && (0 <= minutes() && minutes() <= 59) && (0 <= minutes() && minutes() <= 59) && (0 <= seconds() && seconds() <= 60); (0 <= seconds() && seconds() <= 60); } } sane() is the invariant of a Time object: • valid before every public method • valid after every public method 26 T R Finding Origins A F F I C • Precondition fails = Infection before method • Postcondition fails = Infection after method • All assertions pass = no infection void Time::set_hour(int h) { assert (sane()); // Precondition … assert (sane()); // Postcondition } 27

  10. T R Complex Invariants A F F I C class RedBlackTree { … boolean sane() { assert (rootHasNoParent()); assert (rootIsBlack()); assert (redNodesHaveOnlyBlackChildren()); assert (equalNumberOfBlackNodesOnSubtrees()); assert (treeIsAcyclic()); assert (parentsAreConsistent()); return true; } } 28 T R Assertions A F F I C ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✘ t t 29 T R Focusing A F F I C • All possible influences must be checked • Focusing on most likely candidates • Assertions help in finding infections fast 30

  11. T R Isolation A F F I C • Failure causes should be narrowed down systematically • Use observation and experiments 31 T R Scientific Method A F F I C 1. Observe some aspect of the universe. 2. Invent a hypothesis that is consistent with the observation. 3. Use the hypothesis to make predictions. 4. Tests the predictions by experiments or observations and modify the hypothesis. 5. Repeat 3 and 4 to refine the hypothesis. 32 T R Scientific Method A F F I Problem Report C Hypothesis is supported: Code refine hypothesis Observation Prediction Hypothesis Experiment + Conclusion Run Hypothesis is rejected: create new hypothesis More Runs Diagnosis 33

  12. T R A F F I C 34 T R Explicit Hypotheses A F F I C The execution causes a[0] = 0 Hypothesis The execution causes a[0] = 0 At Line 37, a[0] = 0 should hold. Observe a[0] at Line 37. Keeping everything in a[0] = 0 holds as predicted. Hypothesis is confirmed . memory is like playing Prediction At Line 37, a[0] = 0 should hold. mastermind blind! Experiment Observe a[0] at Line 37. Observation a[0] = 0 holds as predicted. Conclusion Hypothesis is confirmed. 35 T R Explicit Hypotheses A F F I C 36

  13. T T R R Isolate A A F F F F I I C C • We repeat the search for infection origins until we found the defect • We proceed systematically along the scientific method • Explicit steps guide the search – and make it repeatable at any time 37 T R Correction A F F I C Before correcting the defect, we must check whether the defect • actually is an error and • causes the failure Only when we understood both, can we correct the defect 38 T The Devil’s Guide R A F to Debugging ☠ F I C Find the defect by guessing: • Scatter debugging statements everywhere • Try changing code until something works • Don’t back up old versions of the code • Don’t bother understanding what the program should do 39

  14. T The Devil’s Guide R A F to Debugging ☠ F I C Don’t waste time understanding the problem. • Most problems are trivial, anyway. 40 T The Devil’s Guide R A F ☠ to Debugging F I C Use the most obvious fix. • Just fix what you see: x = compute(y) // compute(17) is wrong – fix it if (y == 17) x = 25.15 Why bother going into compute()? 41 T R Successful Correction A F F I C 42

  15. T R Homework A F F I C • Does the failure no longer occur? (If it does still occur, this should come as a big surprise) • Did the correction introduce new problems? • Was the same mistake made elsewhere? • Did I commit the change to version control and problem tracking? 43 The Process T rack the problem R eproduce A utomate F ind Origins F ocus I solate C orrect 44 “The definitive book on debugging” Mehr zum Thema ZELLER – WALTER F. TICHY TU Karlsruhe WHY PROGRAMS FAIL A Guide to Systematic Debugging WHY PROGRAMS FAIL A Guide to Systematic Debugging ANDREAS ZELLER 45

  16. 46 47 48

  17. Failure Causes in GCC Location Failure Cause <Start> argv[3] toplev.c:4755 name toplev.c:2909 dump_base_name c-lex.c:187 finput → _IO_buf_base c-lex.c:1213 nextchar c-lex.c:1213 yyssa[41] c-typeck.c:3615 yyssa[42] c-lex.c:1213 last_insn → fld[1].rtx → … → fld[1].rtx.code c-decl.c:1213 sequence_result[2] → … → fld[1].rtx.code combine.c:4271 x → fld[0].rtx → fld[0].rtx 49 50 51

  18. Automatic Fixes! 52 Automatic Fixes (a) Java Program (b) Failing and Passing Runs (c) Models " ! 53 Automatic Fixes (d) Model Differences (e) Fix Candidates (f) Validated Fix In Socket.java, X X line 356: In Dir.java, In Socket.java, In Socket.java, line 356: > bind() line 356: < unbind() line 356: > bind() > bind() 54

  19. Mining Object Behavior isEmpty() add(1) v: Vector firstElement() remove(1) Mutators Inspectors change state return state Use static analysis to differentiate 55 Building Models isEmpty() add(1) v: Vector false • After each mutator call, we extract attributes and invoke the inspectors • Extracted states form finite state machine 56 Building Models isEmpty() isEmpty() isEmpty() <init> remove(2) remove(3) remove(1) add(1) add(2) add(3) v: Vector false true true 1 2 3 add() <init> add() isEmpty() ¬isEmpty() remove() remove() 57

Recommend


More recommend