A debugger is a program that allows you to step through another program one line at a time. This is very useful when trying to identify incorrect code and analyze how a program "flows". Key concepts include: Breakpoints, Stepping, and Viewing data.
The debugger is a program that can run your program one line at a time. Thus the debugger can show you exactly how the computer sees your code.
You could think of the debugger as "instant replay" (or film review) in sports, allowing you to see "step by step" what happened in a given play. Coaches use this all the time to find the strengths and weaknesses of their team. The debugger does the same thing. It shows you what is happening in your program at any moment in time, and allows you to "step by step" through the program.
Proper use of the debugger is essential to finding semantic (logical) errors in how your program behaves. The debugger should be considered your best friend while programming (that is, unless you can perfectly visualize how your program will run in your head).
Like any tool, using the debugger will take practice, but it is well worth the investment. Using the debugger to find errors can greatly reduce the time it takes to perfect a program.
The "power" of the debugger is that it lets you see the "state" of your program at any point and to advance through your program ("step") one line at a time in the exact same manner that the code is being executed by the computer.
Key things that you can use the debugger to determine are:
In order to use the debugger you need to know about the following concepts:
A computer can only do "one thing at a time". Thus the computer, when running your program, always has the notion of the "current line". Usually, control of the program flows from the current line to the next line down the screen, to the next line, etc. This can be changed by function calls, if statements, loops, etc.
In Matlab, a Green Arrow (in left column) will point to the current line that is about to be executed. .
In GDB (using the GDB debugger in Emacs to debug C programs), a little white arrow will be shown on the left hand side of the window, pointing at the current line.
It should be noted that we don't usually want to start with the first line in a program. We usually have an approximate idea about where the program is incorrect. To tell the compute to "run the program" until a given line, we use the concept of "break points".
Normally when you run a program, even in the debugger, it will start at the beginning of the program and run until completion (or an error occurs).
Often you may know that the error occurs in a certain function (or part of your program), but that function is not utilized by your code until long after the start of the program. Breakpoints tell the debugger where to "halt" the execution of your program so that you can see what is going on. This allows you to quickly get to the proper location in your program.
In Matlab:To "set" a breakpoint, click in the left column on one of the dashes next to the line of code you are interested in. A red dot should appear.
In Matlab to "remove" a breakpoint, click on the "red dot" that represents the breakpoint (in the left column).
In GDB:To "set" a breakpoint, put the cursor on the line you want and press Cntl-Spacebar.
In GDB to "remove" a breakpoint, type "del #", where # is the number of the breakpoint. Type "break" to list all the breakpoints.
Remember, your program will stop at every breakpoint, so you only want a few directly around the "locus" of interest.
Stepping is the action of "telling the debugger" to advance through your program one line at a time. Remember, a computer program is many small steps combined to form a large goal. It is often the case that one of these small steps is "incorrect". To identify which step is incorrect, we "step" through the program, looking at each line of code as we come to it, and seeing what effect this has on the VARIABLES (really the data in the variables).
There are several ways you can tell the debugger to move through the code:
Complete the next line of code. If this line contains a function, go to the first line of the function's code and stop, waiting for the user to now debug the function.
In Matlab: Step In is represented by the arrow between two pages
In GDB: To step to the next line, or into a function, use: "step" (or "s"))
Again, remember, if your arrow is at a function call, you will "enter" the code for the function and stop at the first line of the function.
Stepping over means to move to the next line of code in the current function. Even if the current line is a function call, all the code for that function will be executed (with out you seeing anything but the result), and the new current next line will be the next line of the code that you were looking at.
In Matlab: Step Over: use the button with an arrow by a single page.
In GDB: type "next" or "n"))
If the current line of execution in the program is inside the code of a function and you want to "Finish It" (complete all the rest of the code in the function), you can use the step out command. This will complete all the code in the current function and return you to the previous function that "called" this function.
In Matlab: Step Out is the button with the arrow going up.
In GDB: type "finish".
The continue action tells the computer to "resume" the program (moving forward through the program's code until another breakpoint is encountered or until the program ends).
In Matlab: the continue command is the button with the straight down arrow.
In GDB: you will need to type "continue" or "c" for short.
Once you have used the debugger to find an error in your code you will want to:
In Matlab: Click the downward arrow with red X over it.
In GDB: you don't need to exit the debugger, just make your changes, recompile the program, and then type "run" to start the program over again from the beginning.
Looking at the "state" of your program is VERY important for realizing if you are calculating and storing the correct data in your program.
In Matlab: the "Workspace" window will show you all the variables that are currently "visible" to the function. This is usually limited to the parameters, the return value variable, and any local variables.
You can also type commands or variable names at the debug prompt (Note, the regular Matlab prompt has been changed to a K followed by >>). This allows you to test equations, or variables to make sure the function is acting appropriately.
In GDB: you will need to type "print variable" where variable is the name of the variable you are interested in. Note, you can abbreviate print with "p".
Remember: The state of a program is the values of all the variables in the program. Also, variables "outside" of the functions "workspace" are never available inside a function!
As your program enters more and more "Functions" (when a function calls another function), a "Stack" of functions is created. This represents a "trail" of function calls for your program. You often want to see how "calling" one function affects the "current" function.
In Matlab: to look at the "call stack", click (in the Debug window) on the STACK pull down menu. By selecting the names of the functions you "move up and down on this list" and thus see how your program "got" to where it currently is!
In GDB: type "backtrace" to see all the functions that have been called up to the current line (and the order in which they were called). You can also use "up" or "down" to move up and down the "call stack". Each time you type one of these commands, the other Emacs window should change to show you the code contained in that level of the call stack.
Sometimes, there will be "nested" function calls:
do_my_function( do_your_function(5) );
When you "step in", you will enter the nested function first, so in this case, the do_your_function will be executed first, then the do_my_function.
If you wish to see the execution of "do_my_function" first "step in" to the "do_your_function", then "step out" (or finish that function), and then "step in" again.
Remember, you only have access to the power of the debugger when you use the "debugger", which starts up when you hit "breakpoints" in your code. If you simply "run" the program without any breakpoints, you will not be able to "walk" through your code nor access any of the "power" of the debugger.
Your Code Vs. The Library Code
Matlab (and C) provide many (MANY) functions. It can almost always be assumed that Matlab's (or C's) code is correct. Thus, you do not usually want to "STEP IN" to the Matlab functions, you usually want to "STEP" over them.
On the other hand, sometimes it is informative to see how the Matlab designers wrote their code. It may be even the case that at some point a Matlab function will "call" your code. In these cases, you may well want to "STEP IN" to the Matlab functions.
It should be noted, that while you can step into Matlab code and view their internals, you cannot do this in C.
As a general lesson, you should keep a strong "fire wall" between your code and accessory code (Matlab's or even other Developers). Assume, if an error exists, that the error is in your code. Only when all possibilities have been exhausted, should you consider "debugging" the Matlab core software.
Two Notes: For this class you can always assume Matlab's code is correct.
The only exception to this is if you "PASS IN" the wrong information to
a Matlab function (give it bad values...). In such a case, the result of
the Matlab function may well be "bad".
Garbage In, Garbage Out (GIGO)!
Using a debugger is usually a repetitive process. You write some code, run it, it doesn't work, so you debug it, fix something, run the debugger again, fix something, run the debugger again, etc.
You will often use the following sequence of commands: