cpp10 - debugging

23
Debugging Michael Heron

Upload: michael-heron

Post on 02-Nov-2014

62 views

Category:

Software


0 download

DESCRIPTION

This is an introductory lecture on C++, suitable for first year computing students or those doing a conversion masters degree at postgraduate level.

TRANSCRIPT

Page 1: CPP10 - Debugging

DebuggingMichael Heron

Page 2: CPP10 - Debugging

Introduction

• In the last lecture we talked about how to find flaws in computer programs.• Or at least, find that there are flaws.

• In this lecture we are going to look at strategies for actually locating the errors.• A more subtle skill.

• Debugging a program occurs in two locations.• Compile time (fixing syntax errors)• Run time (fixing logic errors)

Page 3: CPP10 - Debugging

Syntax Errors• C++ error messages are tremendously unhelpful.

• They are useful for people who already know why their code won’t compile.

• Luckily syntax errors are the easiest kind of errors to locate.• The compiler usually knows, to a degree, where the code has

fallen down.

Page 4: CPP10 - Debugging

Compiler Errors

• The key piece of information is the line number.• That’s what narrows down our search.

• Code in C++ has a very strict syntax. • Deviations from this syntax are not tolerated.

• Eventually it becomes second nature to identify a syntax error.• Humans are very good at pattern recognition.

• Until then, need to rely on examples.• Lectures have these, as do your previous programs.

Page 5: CPP10 - Debugging

Logic Errors

• Logic errors are much more difficult to find.• Your program runs, but it doesn’t do what it’s

supposed to do.• A certain kind of mindset is required to be able

to find why code doesn’t work.• Must be patient.

• For complex programs, it can take hours to track down a single annoying bug.

• Must be willing to experiment.• Sometimes errors only reveal clues when the code is

subtly changed.

Page 6: CPP10 - Debugging

Logic Errors• First of all, it’s important to understand what you think the

program is doing.• This won’t necessarily be what it is actually doing.

• Pen and paper important here.• Trace the activity of each line of code.

• Like we do in the lectures and the tutorials.• Draw the flow of logic through the program.

• Represent the state of all variables.• See where they are modified.

Page 7: CPP10 - Debugging

Logic Errors• Once you understand what you think the program is doing,

find out what the program is actually doing.• We can put in debug statements throughout our code to trace

the flow of logic. • Simply using cout to print the contents of variables at key

parts of the program can be invaluable.• You can see when things aren’t doing what they should be doing.

Page 8: CPP10 - Debugging

The Visual Studio Debugger• Visual studio has a powerful debugger built into it.

• It lets us follow the exact operation of the computer at each stage of its execution.

• However, also important to learn how to do it without the debugger.• It’s not always available when you code.

• In fact, good debuggers are unusual in most programming environments.

Page 9: CPP10 - Debugging

Detectin’• There’s a multi-step process we go through to find errors.

• Reproduce the error• So very important!

• Use lots and lots of debugging messages• Simplify• Try things• Understand why it’s not working

• Don’t just fix it

Page 10: CPP10 - Debugging

Reproducing An Error• The most important thing when debugging is to be able to

reliably reproduce the error.• The most frustrating kind of error is the one that only happens

sometimes.• Sometimes it’s possible to put a band-aid solution on a

malfunctioning program.• This will cause problems later on.

• Best to solve the underlying issue.

Page 11: CPP10 - Debugging

Reproducing an Error• An effective testing strategy is the most important thing here.

• You need to direct your tests towards the areas where things are likely to fail.

• It doesn’t have to be as formal as defining actual test cases.• Although that can help.

• If you can isolate the problem to a specific function, try a test harness.

Page 12: CPP10 - Debugging

Example Test Harnessint main() {

int test_x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int test_y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int expected[] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};

int tmp;

for (int i = 0; i < 10; i++) {

tmp = add_nums (test_x[i], test_y[i]);

if (tmp != expected[i]) {

cout << "Error in inputs: " << test_x[i] << ", " << test_y[i]

<< ". Expected " << expected[i] << ", got " << tmp << endl;

}

}

cout << "Testing concluded." << endl;

}

Page 13: CPP10 - Debugging

Example OutputError in inputs: 1, 1. Expected 2, got 1

Error in inputs: 3, 3. Expected 6, got 9

Error in inputs: 4, 4. Expected 8, got 16

Error in inputs: 5, 5. Expected 10, got 25

Error in inputs: 6, 6. Expected 12, got 36

Error in inputs: 7, 7. Expected 14, got 49

Error in inputs: 8, 8. Expected 16, got 64

Error in inputs: 9, 9. Expected 18, got 81

Error in inputs: 10, 10. Expected 20, got 100

Testing concluded.

What’s the likely error here?

Page 14: CPP10 - Debugging

Use Debugging Messages

• When you have found where the error is, put lots of debugging messages in.• Simple cout statements that contain the value of

variables.

• Label these clearly• You need to be able to see where they are coming

from at each part of the program.

• You can get rid of them when you are done.• Comment out rather than delete.

• You may need them again later.

Page 15: CPP10 - Debugging

Simplify• Sometimes there’s just too much code to work out what is

going wrong.• Important to simplify a program when this is occuring.• Comment out lines of code that are doing complex functionality.

• Replace them with simpler versions for testing• For example, if you have a line of code generating a random

number…• … replace it with a non random number for testing.

Page 16: CPP10 - Debugging

Experimentation• The next phase is simply to experiment with the code.

• Change and tweak values to see if it makes a different.• Your process up to this point will give you some code where

there are likely problems.• Focus your testing around there.

Page 17: CPP10 - Debugging

Understanding• Having found the bug, it’s tempting to just fix it.

• Not a great idea, understanding why bugs occur is how you become a better programmer.

• Don’t simply recast the code.• Work out why the code as it stands doesn’t work.

• This is transferable knowledge.

Page 18: CPP10 - Debugging

The Wrong Approachfor (int i = 0; i < someVariable; i++) { }

for (int i = 0; i < someVariable - 1; i++) { }

Your patient detecting has discovered the loop iterates one more time than it should. The easy solution is to simply make it loop one less time. But… that’s not the actual problem.

The problem is that you expected the loop to occur less frequently than it did. It’s a symptom of a larger problem (the code isn’t doing what you think it is), and a quick fix like this will leave problems unsolved for the future.

Page 19: CPP10 - Debugging

A Debugging Exerciseint main() {

int num, num2;

int ans;

num = get_input ("Give me a number");

num2 = get_input ("Give me the power you want that number to");

ans = calculate_power (num, num);

display_answer (ans);

return 0;

}

Page 20: CPP10 - Debugging

Get Input

int get_input (string str) {

int tmp;

cout << str;

cin >> tmp;

return tmp;

}

Page 21: CPP10 - Debugging

Calculate Power

int calculate_power (int num1, int num2) {

int total = 0;

for (int i = 0; i <= num2; i++) {

total = total * num1;

}

return total;

}

Page 22: CPP10 - Debugging

Display Answer

void display_answer (int x) {

cout << "The answer is " << x << endl;

}

This program compiles fine.

It doesn’t give the right output.

Where is the error?

Need a process to find it!

Page 23: CPP10 - Debugging

Summary

• Getting programs to compile is part of the battle.• The bigger battle is – making it work properly

when it does.• This needs a particular kind of mindset to do.

• Bugs don’t get fixed instantly, they need a lot of figuring out in larger programs.

• Important to understand why errors occur.• That’s how you get better at programming generally.