Reliable programming

Similar documents
The compiler is spewing error messages.

1: Introduction to Object (1)

CS354 gdb Tutorial Written by Chris Feilbach

Errors. Lecture 6. Hartmut Kaiser hkaiser/fall_2011/csc1254.html

Chapter01.fm Page 1 Monday, August 23, :52 PM. Part I of Change. The Mechanics. of Change

Chapter 5 Errors. Hyunyoung Lee. Based on slides by Bjarne Stroustrup.

Chapter 5 Errors. Bjarne Stroustrup

MergeSort, Recurrences, Asymptotic Analysis Scribe: Michael P. Kim Date: April 1, 2015

Lecture 4 CSE July 1992

Statistics Case Study 2000 M. J. Clancy and M. C. Linn

MA 1128: Lecture 02 1/22/2018

How to approach a computational problem

Assertions and Exceptions Lecture 11 Fall 2005

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

Lab 7 Unit testing and debugging

CSE 143. Programming is... Principles of Programming and Software Engineering. The Software Lifecycle. Software Lifecycle in HW

Lecture 1: Overview

CS 3 Introduction to Software Engineering. 3: Exceptions

The name of our class will be Yo. Type that in where it says Class Name. Don t hit the OK button yet.

Static Methods. Why use methods?

Unit Testing as Hypothesis Testing

Foundations, Reasoning About Algorithms, and Design By Contract CMPSC 122

MicroSurvey Users: How to Report a Bug

MITOCW watch?v=9h6muyzjms0

Java/RealJ Troubleshooting Guide

MergeSort, Recurrences, Asymptotic Analysis Scribe: Michael P. Kim Date: September 28, 2016 Edited by Ofir Geri

Lecture 3: Linear Classification

Control Structures. Code can be purely arithmetic assignments. At some point we will need some kind of control or decision making process to occur

It s possible to get your inbox to zero and keep it there, even if you get hundreds of s a day.

C++ for Everyone, 2e, Cay Horstmann, Copyright 2012 John Wiley and Sons, Inc. All rights reserved. Using a Debugger WE5.

Computer Labs: Debugging

Software Engineering /48

Object Oriented Software Design - I

Client Code - the code that uses the classes under discussion. Coupling - code in one module depends on code in another module

Creating a new form with check boxes, drop-down list boxes, and text box fill-ins. Customizing each of the three form fields.

Debugging. CSE 2231 Supplement A Annatala Wolf

Principles of Algorithm Design

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

Notes on Turing s Theorem and Computability

Lecture 19 CSE August You taught me Language, and my profit on t is I know how to curse. William Shakspere, The Tempest, I, ii.

CSE 374 Programming Concepts & Tools

Exploring Code with Microsoft Pex

PROBLEM SOLVING 11. July 24, 2012

int n = 10; int sum = 10; while (n > 1) { sum = sum + n; n--; } cout << "The sum of the integers 1 to 10 is " << sum << endl;

Lecture 5 8/24/18. Writing larger programs. Comments. What are we going to cover today? Using Comments. Comments in Python. Writing larger programs

COMP390 (Design &) Implementation

Program development plan

Excel Basics Rice Digital Media Commons Guide Written for Microsoft Excel 2010 Windows Edition by Eric Miller

CS 161 Computer Security

QUIZ. What are 3 differences between C and C++ const variables?

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Sorting lower bound and Linear-time sorting Date: 9/19/17

CS125 : Introduction to Computer Science. Lecture Notes #38 and #39 Quicksort. c 2005, 2003, 2002, 2000 Jason Zych

Documentation Nick Parlante, 1996.Free for non-commerical use.

Supplemental Handout: Exceptions CS 1070, Spring 2012 Thursday, 23 Feb 2012

Text Input and Conditionals

First-Order Translation Checklist

CMSC 201 Fall 2016 Lab 09 Advanced Debugging

COMP1730/COMP6730 Programming for Scientists. Testing and Debugging.

Paxos provides a highly available, redundant log of events

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

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

The Dynamic Typing Interlude

How to Get Your Inbox to Zero Every Day

Software Design COSC 4353/6353 D R. R A J S I N G H

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.

Hardware versus software

Reviewing gcc, make, gdb, and Linux Editors 1

Microsoft Dynamics GP is a robust accounting package that can meet

Background. $VENDOR wasn t sure either, but they were pretty sure it wasn t their code.

Intro. Scheme Basics. scm> 5 5. scm>

XP: Backup Your Important Files for Safety

Window Server 2012 Hyper-V Virtual Machine Snapshots

3 Continuous Integration 3. Automated system finding bugs is better than people

Table of Laplace Transforms

Homework & Debugging Tips

What is version control? (discuss) Who has used version control? Favorite VCS? Uses of version control (read)

Compiling with Multiple Files The Importance of Debugging CS 16: Solving Problems with Computers I Lecture #7

Introduction to Programming

Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn

CITS5501 Software Testing and Quality Assurance Formal methods

Deep C (and C++) by Olve Maudal

Recursively Enumerable Languages, Turing Machines, and Decidability

CS 147: Computer Systems Performance Analysis

A few more things about Agile and SE. Could help in interviews, but don t try to bluff your way through

TEST-DRIVEN DEVELOPMENT

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Priority Queues / Heaps Date: 9/27/17

2SKILL. Variables Lesson 6. Remembering numbers (and other stuff)...

1.7 Limit of a Function

How To Get Your Word Document. Ready For Your Editor

Unit Testing as Hypothesis Testing

Divisibility Rules and Their Explanations

6.001 Notes: Section 6.1

CS 137 Part 2. Loops, Functions, Recursion, Arrays. September 22nd, 2017

GDB Tutorial. A Walkthrough with Examples. CMSC Spring Last modified March 22, GDB Tutorial

COSC 2P91. Bringing it all together... Week 4b. Brock University. Brock University (Week 4b) Bringing it all together... 1 / 22

3 Nonlocal Exit. Quiz Program Revisited

Lecture Transcript While and Do While Statements in C++

Algorithms in Systems Engineering IE172. Midterm Review. Dr. Ted Ralphs

Software Engineering Testing and Debugging Testing

Upgrading Your Geant4 Release

Transcription:

Reliable programming

How to write programs that work Think about reliability during design and implementation Test systematically When things break, fix them correctly Make sure everything stays fixed

A reliable design is Modular: You can break it into pieces and verify each piece separately Robust: Even nonsensical input will cause it to fail in a predictable way Deterministic: If it fails, you can easily make it fail the same way again Testable: You can look inside and see why it s doing what it does

Modular design If you break a system into pieces, then you can examine the communication between the pieces capture communication samples for examination and replay test each piece separately

Testing pieces separately Stable interfaces are the key; changing an interface may force a change in test strategy require coordinated changes on both ends of the changing interface create contradictions among versions Interface changes are much harder to test than implementation changes

Robust design The best bet is for a component to handle all possible inputs gracefully Second best (and often good enough): Fail in a clear way on bad input Worse: Do something random on bad input (garbage in, garbage out) Worst of all: Don t know what input is good and what isn t

Programming without limits One important form of robustness is avoiding fixed limits in programs Library algorithms are a good start Who needs more than two digits in a year, anyway? If you absolutely must have a fixed limit, document and check for it

Deterministic design The hardest programs to test are those that give different output when run twice on the same input interactive programs programs that depend on system state programs that use random numbers Unless you isolate indeterminacy, you have a hard struggle ahead of you

Isolating indeterminacy Make the indeterminate parts of your program as small as you possibly can Define interfaces to the rest of the system Capture sample data flow across those interfaces; use them for testing Example: Capture keystrokes, mouse events, etc. in a GUI

Testable design It is often much easier to determine whether a result is correct than it is to compute it Checking if an array is sorted after the fact Sanity checks on output Data structure audits Such tests can often reveal problems before they affect other components

Assertions If you write #include <assert.h> assert(expr); If expr is zero (false), the program will halt at that point with a diagnostic message (unless preprocessor variable NDEBUG is set).

Logging It can often be useful for programs to leave a trail of bread crumbs while they re running Write significant events into a log file Examine the log file afterwards to see if everything worked OK You can turn off logging later if it turns out to cost too much

A reliable implementation is Well specified Easy to understand Easy to explain Careful about edge cases

Well specified implementation Careful specification is important doesn t have to be formal has to exist probably in writing How can you know if a program is doing what it s supposed to do if you don t know what it s supposed to do? A specification gives you a test standard

Clean implementation If it s obvious how a program works, it s likely that it does work and if it doesn t work, the reason is likely to be obvious Messy implementation is often a symptom of not understanding the problem thoroughly

Explaining programs The best way to be sure you understand something or to find out where you don t is to try to explain it to someone else This fact is sometimes formalized in inspections, code reviews, etc. If you don t understand why something doesn t work, try to prove that it works

Edge cases Lots of programs deal with collections When asking if such a program works, consider looking at the smallest possible input (usually null) the next smallest input (a single element) the largest possible input one less than the largest possible one more than the largest possible

Proving programs Sometimes it is possible to prove that a program works. For example: double power(double x0, double n0) { double x = x0; unsigned n = n0; double r = 1; } while (n!= 0) { r *= x; --n; } return r; Loop invariant: r = x (n0 n)

Systematic testing If a component has a clear specification, and input and output that can be captured, then it is easy to generate test cases You (or better yet someone else) can write test cases together with the code Be sure you can run them automatically

What is most important to test? The most important parts of the program those on which many other parts depend The most difficult parts of the program Parts whose performance is critical to the performance of the whole system

Unit testing You should have a collection of tests for each component additional tests for the whole system programs to run tests automatically If you are sure that each component works before you put the system together, it will save lots of work in testing the whole system

Debugging A necessary nuisance Easy to get wrong Requires a special state of mind Many tools available some of them even work

A necessary nuisance Thinking carefully in advance can avoid many bugs Looking carefully at your programs and trying to prove them can avoid others Type checking and other linguistic tools can avoid still more Nevertheless, sometimes things just don t work right

How to avoid making things worse Be sure that you re running the program that you re trying to fix Be sure it s broken before you fix it Be sure that what you re trying to fix is actually the part that s broken Be sure that you understand completely why what you re doing will fix the bug that you found

A special state of mind Your program is broken because you misunderstood something but if you knew what you had misunderstood, you wouldn t have misunderstood it Therefore, you have to assume that much of what you know might be wrong

How not to do it Find a piece of code that looks like it might be related to the problem Change it at random and try it out If it looks like it worked, you re done Otherwise, go back to the beginning

A more productive approach Find a piece of code that looks relevant to the problem Form a hypothesis about why the code is wrong Write a test case that makes it fail Fix it and verify that it now works Save that test case you ll need it later

Simplifying the bug hunt If you can break it, you re almost done What did you change since it worked? If the input is right and the output is wrong, what s the first point at which the program is misbehaving? This is where the ability to capture inter-module communication comes in handy

Once you think you ve found it Do you understand how the bug you found accounts for the behavior you saw? All of it? Does fixing the bug correct the behavior in the way you expected? If not, did you remember to recompile the program before running it again? Did fixing it break anything else?

Debugging tools Useful tools: stack traces, breakpoints, ability to print variables, etc. Less useful for interactive or distributed programs Sometimes have their own bugs Supplement, not substitute, for careful testing, source code control, etc.

Did fixing it break anything else? 100 little bugs in the code, 100 bugs in the code; Fix a bug, compile it again, 101 little bugs in the code

Ensuring that bugs stay fixed Remember that test case I said you d need later? Try to build a library of test cases that correspond to bugs that you ve found a mechanism for running all those test cases automatically every time you change anything significant A good library of test cases can be more valuable than the system itself

Example: compiler test library (1988) For every bug report, we created a program that reproduces the bug Every time we built an internal version of the compiler (at least weekly), we ran every test case and reported the ones that now failed that used to work

When does a compiler test work? If the program is expected to run without diagnostics, we designed it to print pairs of identical output lines If the program is expected to produce a message, we put a special comment in the source code; a little program compared the compiler output with the comments to verify the messages

Running batches of tests Every test gets a number A little program recompiles the compiler and runs every test The result is a list of tests passed and failed, which we compare with last week s results We really care about tests that used to pass and now fail

Summary It is much harder to make a system reliable as an afterthought than to design it that way from the start Reliability demands constant vigilance