Software Engineering

Similar documents
Software Engineering Testing and Debugging Debugging

Today s Topic. Software Engineering Testing and Debugging Debugging. Today s Topic. The Main Steps in Systematic Debugging

Testing, Debugging, Program Verification

Software Engineering

Software Engineering

Softwaretechnik. Lecture 08: Testing and Debugging Overview. Peter Thiemann SS University of Freiburg, Germany

Softwaretechnik. Lecture 08: Testing and Debugging Overview. Peter Thiemann SS University of Freiburg, Germany

The NetBeans IDE is a big file --- a minimum of around 30 MB. After you have downloaded the file, simply execute the file to install the software.

CSE 374 Programming Concepts & Tools

CSE 374 Programming Concepts & Tools. Brandon Myers Winter 2015 Lecture 11 gdb and Debugging (Thanks to Hal Perkins)

DEBUGGING: OBSERVING AND TRACKING

Software Engineering

Xcode Tricks. ios App Development Fall 2010 Lecture 13

Regression testing. Whenever you find a bug. Why is this a good idea?

Debugging in Small Basic is the process of analysing a program to detect and fix errors or improve functionality in some way.

Lab 4: Imperative & Debugging 12:00 PM, Feb 14, 2018

GETTING STARTED WITH ECLIPSE Caitrin Armstrong

Software Quality. Debugging " Martin Glinz. Chapter 4. Department of Informatics!

Intro to MS Visual C++ Debugging

First, let s just try to run the program. When we click the button we get the error message shown below:

Understanding the Program Run

7 The Integrated Debugger

CSE 351. GDB Introduction

We first learn one useful option of gcc. Copy the following C source file to your

Changing the Embedded World TM. Module 3: Getting Started Debugging

The compiler is spewing error messages.

Testing and Debugging

hw6, BFS, debugging CSE 331 Section 5 10/25/12 Slides by Kellen Donohue

Reviewing gcc, make, gdb, and Linux Editors 1

Software Engineering Testing and Debugging Testing

NetBeans IDE Field Guide

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

CS111: PROGRAMMING LANGUAGE II

A Tutorial for ECE 175

JCreator. Starting JCreator

CSCI0330 Intro Computer Systems Doeppner. Lab 02 - Tools Lab. Due: Sunday, September 23, 2018 at 6:00 PM. 1 Introduction 0.

Flow of Control: Loops

Parallel Debugging. ª Objective. ª Contents. ª Learn the basics of debugging parallel programs

Steps for project success. git status. Milestones. Deliverables. Homework 1 submitted Homework 2 will be posted October 26.

Announcements. Lab Friday, 1-2:30 and 3-4:30 in Boot your laptop and start Forte, if you brought your laptop

Part 5. Verification and Validation

Debugging Techniques. CEFET Engineering Week

Eclipse Tutorial. For Introduction to Java Programming By Y. Daniel Liang

MEDIA COMPUTATION DRJAVA. Lecture 11.3 November 7, 2008

Second assignment came out Monday evening. Find defects in Hnefetafl rules written by your classmates. Topic: Code Inspection and Testing

Guidelines for Writing C Code

Testing and Debugging

QUIZ Friends class Y;

CS 520 Theory and Practice of Software Engineering Fall 2018

Debugging in AnyLogic. Nathaniel Osgood CMPT

CS354 gdb Tutorial Written by Chris Feilbach

CS-152: Software Testing

CS2: Debugging in Java

Supplement: Visual C++ Debugging

Programming Studio #9 ECE 190

NetBeans Tutorial. For Introduction to Java Programming By Y. Daniel Liang. This tutorial applies to NetBeans 6, 7, or a higher version.

Automated Debugging in Eclipse (at the touch of not even a button)

Getting Started (1.8.7) 9/2/2009

CS 231 Data Structures and Algorithms, Fall 2016

Outline. Computer programming. Debugging. What is it. Debugging. Hints. Debugging

Computer Science II Lab 3 Testing and Debugging

Debugging HPC Applications. David Lecomber CTO, Allinea Software

12/14/2016. Errors. Debugging and Error Handling. Run-Time Errors. Debugging in C# Debugging in C# (continued)

Reliable programming

Jtest Tutorial. Tutorial

An Overview of ABAP Debugger Settings and System Areas

Object Oriented Programming

Software Exorcism: A Handbook for Debugging and Optimizing Legacy Code

Debugging. John Lockman Texas Advanced Computing Center

CSE 501: Compiler Construction. Course outline. Goals for language implementation. Why study compilers? Models of compilation

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

Lab 8 - Vectors, and Debugging. Directions

Using the KD30 Debugger

Chapter 4 Introduction to Control Statements

Verification and Validation. Assuring that a software system meets a user s needs. Verification vs Validation. The V & V Process

1. Allowed you to see the value of one or more variables, or 2. Indicated where you were in the execution of a program

Using the Xcode Debugger

Debugging with gdb and valgrind

Verification and Validation. Ian Sommerville 2004 Software Engineering, 7th edition. Chapter 22 Slide 1

Laboratory Assignment #4 Debugging in Eclipse CDT 1

Debugging Abstract State Machine Specifications: An Extension of CoreASM

3 Getting Started with Objects

Debugging R code. by Marek Rychlik February 28, 2009

Atropos User s manual

BASICS OF THE RENESAS SYNERGY PLATFORM

Static Analysis and Bugfinding

Global Optimization. Lecture Outline. Global flow analysis. Global constant propagation. Liveness analysis. Local Optimization. Global Optimization

Testing. Prof. Clarkson Fall Today s music: Wrecking Ball by Miley Cyrus

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

EXAMINING THE CODE. 1. Examining the Design and Code 2. Formal Review: 3. Coding Standards and Guidelines: 4. Generic Code Review Checklist:

CS 314 Principles of Programming Languages. Lecture 9

Objectives. Chapter 19. Verification vs. validation. Topics covered. Static and dynamic verification. The V&V process

Debugging (Part 1) The material for this lecture is drawn, in part, from The Practice of Programming (Kernighan & Pike) Chapter 5

Debugging. ICS312 Machine-Level and Systems Programming. Henri Casanova

Program Design: Using the Debugger

Lecture 19. Delta Debugging Cooperative Bug Isolation. EE 382V Spring 2009 Software Evolution - Instructor Miryung Kim

Debugging and Profiling

An Introduction to Komodo

CS/COE 0449 term 2174 Lab 5: gdb

Jlint status of version 3.0

Transcription:

Software Engineering Lecture 12: Testing and Debugging Debugging Peter Thiemann University of Freiburg, Germany 13.06.2013

Today s Topic Last Lecture Bug tracking Program control Design for Debugging Input simplification

Today s Topic Last Lecture Bug tracking Program control Design for Debugging Input simplification This Lecture Execution observation With logging Using debuggers Tracking causes and effects

The Main Steps in Systematic Debugging Program State Time Reproduce failure with test input

The Main Steps in Systematic Debugging Program State Time Reduction of failure-inducing problem

The Main Steps in Systematic Debugging Program State Time State known to be healthy

The Main Steps in Systematic Debugging Program State Time State known to be infected

The Main Steps in Systematic Debugging Program State Time State where failure becomes observable

The Main Steps in Systematic Debugging Program State Time latest state known to be healthy earliest state known to be infected Separate healthy from infected states

The Main Steps in Systematic Debugging Program State Time latest state known to be healthy earliest state known to be infected Separate healthy from infected states Separate relevant from irrelevant states

Central Problem How can we observe a program run?

Central Problem How can we observe a program run? Challenges/Obstacles Observation of intermediate state not part of functionality Observation can change the behavior Narrowing down to relevant time/state sections

The Naive Approach: Print Logging Println Debugging Manually add print statements at code locations to be observed System.out.println("size = "+ size);

The Naive Approach: Print Logging Println Debugging Manually add print statements at code locations to be observed System.out.println("size = "+ size); Simple and easy Can use any output channel No tools or infrastructure needed, works on any platform

The Naive Approach: Print Logging Println Debugging Manually add print statements at code locations to be observed System.out.println("size = "+ size); Simple and easy Can use any output channel No tools or infrastructure needed, works on any platform Code cluttering Output cluttering (at least need to use debug channel) Performance penalty, possibly changed behavior (timing,... ) Buffered output lost on crash Source code required, recompilation necessary

Logging Frameworks Example (Logging Framework for Java) java.util.logging Main principles of Java logging Each class can have its own Logger object Each logger is associated with a level and a handler Levels: FINEST < FINER < FINE < CONFIG < INFO < WARNING < SEVERE Handlers: j.u.l.consolehandler, j.u.l.filehandler Example: log message with mylogger and level INFO: mylogger.info(object message); Logging can be controlled by program or properties file: which logger, level, filter, formatting, handler, etc. No recompilation necessary for reconfiguration

Evaluation of Logging Frameworks Output cluttering can be mastered Small performance overhead Exceptions are loggable Log complete up to crash Instrumented source code reconfigurable w/o recompilation Code cluttering don t try to log everything! Code cluttering avoidable with aspects, but also with Debuggers

What is a Debugger? Basic Functionality of a Debugger Execution Control Stop execution on specified conditions: breakpoints Interpretation Step-wise execution of code State Inspection Observe value of variables and stack State Change Change state of stopped program Historical term Debugger is misnomer as there are many debugging tools

What is a Debugger? Basic Functionality of a Debugger Execution Control Stop execution on specified conditions: breakpoints Interpretation Step-wise execution of code State Inspection Observe value of variables and stack State Change Change state of stopped program Historical term Debugger is misnomer as there are many debugging tools Traditional debuggers (gdb for C) based on command line I/F We use the built-in GUI-based debugger of the Eclipse framework Feel free to experiment with other debuggers!

Running Example 1 public static int search ( int [] array, 2 int target ) { 3 4 int low = 0; 5 int high = array. length ; 6 int mid ; 7 while ( low <= high ) { 8 mid = ( low + high ) /2; 9 if ( target < array [ mid ] ) { 10 high = mid - 1; 11 } else if ( target > array [ mid ] ) { 12 low = mid + 1; 13 } else { 14 return mid ; 15 } 16 } 17 return -1; 18 }

Eclipse Debugger Open directory BinSearch, create project Search Create/show run configuration testbin1 Run testbin1 Open Debugging view of project Search

Testing Running a few test cases... search( {1,2}, 1 ) == 0

Testing Running a few test cases... search( {1,2}, 1 ) == 0 search( {1,2}, 2 ) == 1

Testing Running a few test cases... search( {1,2}, 1 ) == 0 search( {1,2}, 2 ) == 1 search( {1,2}, 4 ) throws ArrayIndexOutOfBoundsException: 3

Testing Running a few test cases... search( {1,2}, 1 ) == 0 search( {1,2}, 2 ) == 1 search( {1,2}, 4 ) throws ArrayIndexOutOfBoundsException: 3 Example taken from a published Java text book :-(

Halting Program Execution Breakpoint A program location that, when it is reached, halts execution Example (Setting Breakpoint) In search() at loop, right-click, toggle breakpoint Some remarks on breakpoints Set breakpoint at last statement where state is known to be healthy Formulate healthiness as an explicit hypothesis In Eclipse, not all lines can be breakpoints, because these are actually inserted into bytecode Remove breakpoints when no longer needed

Resuming Program Execution Example (Execution Control Commands) Start debugging of run configuration testbin1 Resume halts when breakpoint is reached in next loop execution Disable breakpoint for this session Resume executes now until end Remove from debug log (Remove All Terminated) Enable breakpoint again in Breakpoints window Close debugging perspective

Step-Wise Execution of Programs Step-Wise Execution Commands Step Into Execute next statement, then halt Step Over Consider method call as one statement Some remarks on step-wise execution Usually Java library methods stepped over They should not contain defects You probably don t have the source code To step over bigger chunks, change breakpoints, then resume

Inspecting the Program State Inspection of state while program is halted Variables window Unfold reference types Pretty-printed in lower half of window Tooltips for variables in focus in editor window Recently changed variables are highlighted

Inspecting the Program State Inspection of state while program is halted Variables window Unfold reference types Pretty-printed in lower half of window Tooltips for variables in focus in editor window Recently changed variables are highlighted Example (Tracking search()) Start debugging at beginning of loop (testbin2) Step through one execution of loop body After first execution of loop body low==high==2 Therefore, mid==2, but array[2] doesn t exist! If target is greater than all array elements, eventually low==mid==array.length

Changing the Program State Hypothesis for Correct Value Variable high should have value array.length-1

Changing the Program State Hypothesis for Correct Value Variable high should have value array.length-1 Changing state while program is halted Right-click on identifier in Variables window, Change Value

Changing the Program State Hypothesis for Correct Value Variable high should have value array.length-1 Changing state while program is halted Right-click on identifier in Variables window, Change Value Example (Fixing the defect in the current run) At start of second round of loop, set high to correct value 1 Resuming execution now yields correct result

Watching States with Debuggers Halting Execution upon Specific Conditions Use Boolean Watch expression in conditional breakpoint

Watching States with Debuggers Halting Execution upon Specific Conditions Use Boolean Watch expression in conditional breakpoint Example (Halting just before exception is thrown) From test run: argument mid of array is 2 at this point Create breakpoint at code position where evaluation takes place Add watch expression mid==2 to breakpoint properties Disable breakpoint at start of loop Execution halts exactly when mid==2 becomes true

Watching States with Debuggers Halting Execution upon Specific Conditions Use Boolean Watch expression in conditional breakpoint Example (Halting just before exception is thrown) From test run: argument mid of array is 2 at this point Create breakpoint at code position where evaluation takes place Add watch expression mid==2 to breakpoint properties Disable breakpoint at start of loop Execution halts exactly when mid==2 becomes true Hints on watch expressions Make sure scope of variables in watch expressions is big enough

Evaluation of Debuggers Code cluttering completely avoided Prudent usage of breakpoints/watches reduces states to be inspected Full control over all execution aspects Debuggers are interactive tools, re-use difficult Performance can degrade, disable unused watches Inspection of reference types (lists, etc.) is tedious

Evaluation of Debuggers Code cluttering completely avoided Prudent usage of breakpoints/watches reduces states to be inspected Full control over all execution aspects Debuggers are interactive tools, re-use difficult Performance can degrade, disable unused watches Inspection of reference types (lists, etc.) is tedious Important Lessons Both, logging and debuggers are necessary and complementary Need visualization tools to render complex data structures Minimal/small input, localisation of unit is important

Tracking Causes and Effects Determine defect that is origin of failure Fundamental problem Program executes forward, but need to reason backwards from failure Example In search() the failure was caused by wrong value mid, but the real culprit was high

Effects of Statements Fundamental ways how statements may affect each other Write Change the program state Assign a new value to a variable read by another statement Control Change the program counter Determine which statement is executed next

Effects of Statements Fundamental ways how statements may affect each other Write Change the program state Assign a new value to a variable read by another statement Control Change the program counter Determine which statement is executed next Statements with Write Effect (in Java) Assignments I/O, because it affects buffer content new(), because object initialisation writes to fields

Effects of Statements Fundamental ways how statements may affect each other Write Change the program state Assign a new value to a variable read by another statement Control Change the program counter Determine which statement is executed next Statements with Control Effect (in Java) Conditionals, switches Loops: determine whether their body is executed Dynamic method calls: implicit case distinction on implementations Abrupt termination statements: break, return Exceptions: potentially at each object or array access!

Statement Dependencies Definition (Data Dependency) Statement B is data dependent on statement A iff 1. A writes to a variable v that is read by B and 2. There is at least one execution path between A and B in which v is not written to The outcome of A can directly influence a variable read in B

Statement Dependencies Definition (Control Dependency) Statement B is control dependent on statement A iff There is an execution path from A to B such that: For all statements S A on the path, all execution paths from S to the method exit pass through B and There is an execution path from A to the method exit that does not pass through B The outcome of A can influence whether B is executed

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = ( low + high ) /2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1;

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; mid is data-dependent on this statement

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = ( low + high ) /2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; mid is control-dependent on the while statement

Computing Backward Dependencies Definition (Backward Dependency) Statement B is backward dependent on statement A iff There is a sequence of statements A = A 1, A 2,..., A n = B such that: 1. for all i, A i+1 is either control dependent or data dependent on A i 2. there is at least one i with A i+1 being data dependent on A i The outcome of A can influence the program state in B

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = ( low + high ) /2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1;

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; mid is backward-dependent on data- and control- dependent statement

Example 1 int low = 0; 2 int high = array.length; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; mid is backward-dependent on data- and control- dependent statement

Example 1 int low = 0; 2 int high = array.length; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; Backward-dependent statements for first execution of loop body

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; Backward-dependent statements for repeated execution of loop body

Systematic Discovery of Defects Program State Time latest state known to be healthy earliest state known to be infected Separate healthy from infected states Separate relevant from irrelevant states

Systematic Discovery of Defects Program State Time Defect latest state known to be healthy earliest state known to be infected Separate healthy from infected states Separate relevant from irrelevant states

Systematic Discovery of Defects Program State Time Defect latest state known to be healthy earliest state known to be infected Separate healthy from infected states Separate relevant from irrelevant states Compute backward-dependent statements from infected locations

Algorithm: Systematic Discovery of Defects Invariant: I is a set of locations (variable set V and statement S) such that each v V is infected after executing S. 1. Initialize I := {infected location reported by failure} 2. Choose a current, infected location L = (V, S) I 3. Let I := I \ {L} 4. Let C := accumulate a set of candidates 5. For each statement S that may contain origin of defect: S backwards depends on S in one step in execution path 5.1 Let M be the set of variables that is written in S and infected 5.2 If M let C := C {(M, S )} 6. If C (there are infected predecessors): 6.1 Let I := I C 6.2 Goto 2. 7. L depends only on healthy locations, it must be the infection site!

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = ( low + high ) /2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; mid is infected, mid==low==high==2

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; Look for origins of low and high

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; low was changed in previous loop execution, value low==1 seems healthy

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; high ==2 set at start (if-branch not taken when target not found), infecte

Example 1 int low = 0; 2 int high = array. length ; 3 int mid ; 4 while ( low <= high ) { 5 mid = (low + high)/2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; high does not depend on any other location found infection site!

Example 1 int low = 0; 2 int high = array.length - 1 ; 3 int mid ; 4 while ( low <= high ) { 5 mid = ( low + high ) /2; 6 if ( target < array [ mid ] ) { 7 high = mid - 1; 8 } else if ( target > array [ mid ] ) { 9 low = mid + 1; 10 } else { 11 return mid ; 12 } 13 } 14 return -1; Fixed defect

After Fixing the Defect Failures that exhibited a defect become new test cases after the fix used for regression testing Use existing unit test cases to test a suspected method in isolation make sure that your bug fix did not introduce new bugs exclude wrong hypotheses about the defect

Open Questions 1. How is evaluation of test runs related to specification? So far: wrote oracle program or evaluated interactively How to check automatically whether test outcome conforms to spec? 2. It is tedious to write test cases by hand Easy to forget cases Java: aliasing, run-time exceptions 3. When does a program have no more bugs? How to prove correctness without executing many paths?

Literature for this Lecture Essential Zeller Why Programs Fail: A Guide to Systematic Debugging, Morgan Kaufmann, 2005 Chapters 7, 8, 9