Debugging

Dr. Jonathan Phillips Utah State University “My program is broken!” • Options: • Have my friend fix it for me • Have the TAs fix it for me • Have Dr. Phillips fix it for me • FIX IT YOURSELF!!! • A ALWAYS does EXACTLY what the told it to do!!! • If your program doesn’t work, it’s NOT the computer’s or the compiler’s fault • The computer is not a teenager: it doesn’t selectively obey, it ALWAYS obeys Techniques 1. Determine whether you have a syntax error or a logical error • Syntax error – code won’t compile • Logical error – code compiles, but doesn’t execute as it should Syntax Errors • Caught by compiler • Will always give you an error or warning message • READ THE MESSAGES • Google is your friend! #include Example int main(void) { char alpha[26]; char i;

for (i='a'; i<='z'; i++) { alpha[i-'a'] = i; }

for (i=25; i >= 0; i--) { cout << alpha[i]; } cout << endl;

return 0; } #include Example int main(void) { char alpha[26]; char i;

for (i='a'; i<='z'; i++) { alpha[i-'a'] = i; }

for (i=25; i >= 0; i--) { cout << alpha[i]; } cout << endl;

return 0; } Logical Errors

• Not caught by compiler • Program runs, but doesn’t always do what we expected • For this reason, it is dangerous to use the compiler as a !!! • Examples • Loops run forever • Loops don’t run at all • If / Else is never true / never false • Math is wrong • Assignment instead of comparison • Extra semicolon • Missing {} Techniques for Debugging Logical Errors 1. Add temporary code to gain insight into what is going on • Print statements • cout, cerr • More information is better • Pause program execution • cin.ignore() Example – Function always returns 0… Example – Better? Example – Better? Example – Better? Techniques for Debugging Logical Errors 1. Add temporary code to gain insight into what is going on • Print statements • cout, cerr • More information is better • Pause program execution • cin.ignore() 2. Use a debugging tool • has an integrated debugger • The GNU tool chain (gcc / g++) provides gdb Microsoft Visual Studio Debugger

• Features • Pause program execution (breakpoints) • View values of variables • Watch CPU and memory usage over time • Step forward one instruction at a time • Tutorials and information from Microsoft • https://docs.microsoft.com/en-us/visualstudio/debugger/index Starting Microsoft Visual Studio Debugger

• Click here • or, Debug -> Start Debugging • or, F5 Breakpoints in Microsoft Visual Studio Debugger

• Click in the “gutter” next to the line number of interest • A red ball appears if a breakpoint can happen here • Start the debugger. Execution will pause *before* the line of interest is executed • There can be multiple breakpoints Breakpoints in Microsoft Visual Studio Debugger

• When execution hits the breakpoint • Yellow arrow • Active variables and their values show up in the “Autos” tab Watch in Microsoft Visual Studio Debugger

• We can manually add variables or expressions to the “Watch 1” tab • Click on Debug->QuickWatch, then type in expression to add Life After the Breakpoint

• Options include • Running (until another breakpoint is hit) • Stepping • Step Into – progresses to next instruction; enters function calls • Step Over – progresses to next instruction; does not enter function calls • Step Out – gets out of the current function • Stopping the debugger – Click on the Red Box Techniques for Debugging Logical Errors 1. Add temporary code to gain insight into what is going on • Print statements • cout, cerr • More information is better • Pause program execution • cin.ignore() 2. Use a debugging tool • Microsoft Visual Studio has an integrated debugger • The GNU tool chain (gcc / g++) provides gdb gdb (Gnu Debugger)

• https://www.gnu.org/software/gdb/documentation/ • Provides the same functionality as Visual Studio debugger, but from the command line • Breakpoints • Stepping • Continue gdb (Gnu Debugger)

• Compiling a program for use with gdb • Compile using gcc or g++ as usual • Must include the –g option • This includes debugging information in the executable Running gdb

• gdb .exe gdb – Setting a Breakpoint gdb – Setting a Breakpoint • syntax: • (gdb) break .cpp : linenum gdb – Running • syntax: • (gdb) run gdb – Seeing values of variables • syntax: • print Life after the gdb breakpoint

• step: run to the next source line • step : run the next source lines • next: similar to step, but don’t enter function calls • continue: run until the next breakpoint (or program end) is reached Exiting gdb • q