Search

3.6 — Using an integrated debugger: Stepping

When you run your program, execution begins at the top of the main function, and then proceeds sequentially statement by statement, until the program ends. At any point in time while your program is running, the program is keeping track of a lot of things: the value of the variables you’re using, which functions have been called (so that when those functions return, the program will know where to go back to), and the current point of execution within the program (so it knows which statement to execute next). All of this tracked information is called your program state (or just state, for short).

In previous lessons, we explored various ways to alter your code to help with debugging, including printing diagnostic information or using a logger. These are simple methods for examining the state of a program while it is running. Although these can be effective if used properly, they still have downsides: they require altering your code, which takes time and can introduce new bugs, and they clutter your code, making the existing code harder to understand.

Behind the techniques we’ve shown so far is an unstated assumption: that once we run the code, it will run to completion (only pausing to accept input) with no opportunity for us to intervene and inspect the results of the program at whatever point we want.

However, what if we were able to remove this assumption? Fortunately, we can. Most modern IDEs come with an integrated tool called a debugger that is designed to do exactly this.

The debugger

A debugger is a computer program that allows the programmer to control how a program executes and examine the program state while the program is running. For example, the programmer can use a debugger to execute a program line by line, examining the value of variables along the way. By comparing the actual value of variables to what is expected, or watching the path of execution through the code, the debugger can help immensely in tracking down semantic (logic) errors.

The power behind the debugger is twofold: the ability to precisely control execution of the program, and the ability to view (and modify, if desired) the program’s state.

Early debuggers, such as gdb, were separate programs that had command-line interfaces, where the programmer had to type arcane commands to make them work. Later debuggers (such as early versions of Borland’s turbo debugger) were still standalone, but came with their own “graphical” front ends to make working with them easier. Most modern IDEs available these days have an integrated debugger -- that is, a debugger uses the same interface as the code editor, so you can debug using the same environment that you use to write your code (rather than having to switch programs).

Nearly all modern debuggers contain the same standard set of basic features -- however, there is little consistency in terms of how the menus to access these features are arranged, and even less consistency in the keyboard shortcuts. Although our examples will use screenshots from Microsoft Visual Studio (and we’ll cover how to do everything in Code::Blocks as well), you should have little trouble figuring out how to access each feature we discuss no matter which development environment you are using, even one we’re not explicitly covering.

The remainder of this chapter will be spent learning how to use the debugger.

Tip

Don’t neglect learning to use a debugger. As your programs get more complicated, the amount of time you spend learning to use the integrated debugger effectively will pale in comparison to amount of time you save finding and fixing issues.

Warning

Before proceeding with this lesson (and subsequent lessons related to using a debugger), make sure your project is compiled using a debug build configuration (see 0.9 -- Configuring your compiler: Build configurations for more information). If you’re compiling your project using a release configuration instead, the functionality of the debugger may not work correctly.

For Code::Blocks users

If you’re using Code::Blocks, your debugger may or may not be set up correctly. Let’s check.

First, go to Settings menu > Debugger…. Next, open the GDB/CDB debugger tree on the left, and choose Default. A dialog should open that looks something like this:

If you see a big red bar where the “Executable path” should be, then you need to locate your debugger. To do so, click the button to the right of the Executable path field. Next, find the “gdb32.exe” file on your system -- mine was in C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb32.exe. Then click OK.

For Code::Blocks users

There have been reports that the Code::Blocks integrated debugger (GDB) can have issues recognizing some file paths that contain spaces or non-English characters in them. If the debugger appears to be malfunctioning as you go through these lessons, that could be a reason why.

Stepping

We’re going to start our exploration of the debugger by first examining some of the debugging tools that allow us to control the way a program executes.

Stepping is the name for a set of related debugger features that let us execute (step through) our code statement by statement.

There are a number of related stepping commands that we’ll cover in turn.

Step into

The step into command executes the next statement in the normal execution path of the program, and then pauses execution of the program so we can examine the program’s state using the debugger. If the statement being executed contains a function call, step into causes the program to jump to the top of the function being called, where it will pause.

Let’s take a look at a very simple program:

Let’s debug this program using the step into command.

First, locate and then execute the step into debug command once.

For Visual Studio users

In Visual Studio, the step into command can be accessed via Debug menu > Step Into, or by pressing the F11 shortcut key.

For Code::Blocks users

In Code::Blocks, the step into command can be accessed via Debug menu > Step into, or by pressing the Shift-F7

For other compilers

If using a different IDE, you’ll likely find the step into command under a Debug or Run menu.

Because our program wasn’t running, when you execute the your first debug command, you may see quite a few things happen:

  • The program will recompile if needed.
  • The program will begin to run. Because our application is a console program, a console output window should open. It will be empty because we haven’t output anything yet.
  • Your IDE may open some diagnostic windows, which may have names such as “Diagnostic Tools”, “Call Stack”, and “Watch”. We’ll cover what some of these are later -- for now you can ignore them.

Because we did a step into, you should now see some kind of marker appear to the left of the opening brace of function main (line 9). In Visual Studio, this marker is a yellow arrow (Code::Blocks uses a yellow triangle). If you are using a different IDE, you should see something that serves the same purpose.

This arrow marker indicates that the line being pointed to will be executed next. In this case, the debugger is telling us that the next line to be executed is the opening brace of function main (line 9).

Choose step into to execute the opening brace, and the arrow will move to the next statement (line 10).

This means the next line that will be executed is the call to function printValue.

Choose step into again. Because this statement contains a function call to printValue, we step into the function, and the arrow will move to the top of the body of printValue (line 4).

Choose step into again to execute the opening brace of function printValue, which will advance the arrow to line 5.

Choose step into yet again, which will execute the statement std::cout << value and move the arrow to line 6.

Warning

Because operator<< is implemented as a function, your IDE may step into the implementation of operator<< instead.

If this happens, you’ll see your IDE open a new code file, and the arrow marker will move to the top of a function named operator<< (this is part of the standard library). Close the code file that just opened, then find and execute step out debug command (instructions are below under the “step out” section, if you need help).

Now because std::cout << value has executed, and we should now see the value 5 appear in the console window.

Choose step into again to execute the closing brace of function printValue. At this point, printValue has finished executing and control is returned to main.

You will note that the arrow is again pointing to printValue!

While you might think that the debugger intends to call printValue again, in actuality the debugger is just letting you know that it is returning from the function call.

Choose step into three more times. At this point, we have executed all the lines in our program, so we are done. Some debuggers will terminate the debugging session automatically at this point, others may not. If your debugger does not, you may need to find a "Stop Debugging" command in your menus (in Visual Studio, this is under Debug > Stop Debugging).

Note that Stop Debugging can be used at any point in the debugging process to end the debugging session.

Congratulations, you've now stepped through a program and watched every line execute!

Step over

Like step into, The step over command executes the next statement in the normal execution path of the program. However, whereas step into will enter function calls and execute them line by line, step over will execute an entire function without stopping and return control to you after the function has been executed.

For Visual Studio users

In Visual Studio, the step over command can be accessed via Debug menu > Step Over, or by pressing the F10 shortcut key.

For Code::Blocks users

In Code::Blocks, the step over command is called Next line instead, and can be accessed via Debug menu > Next line, or by pressing the F7 shortcut key.

Let's take a look at an example where we step over the function call to printValue:

First, use step into on your program until the execution marker is on line 10:

Now, choose step over. The debugger will execute the function (which prints the value 5 in the console output window) and then return control to you on the next statement (line 12).

The step over command provides a convenient way to skip functions when you are sure they already work or are not interested in debugging them right now.

Step out

Unlike the other two stepping commands, Step out does not just execute the next line of code. Instead, it executes all remaining code in the function currently being executed, and then returns control to you when the function has returned.

For Visual Studio users

In Visual Studio, the step out command can be accessed via Debug menu > Step Out, or by pressing the Shift-F11 shortcut combo.

For Code::Blocks users

In Code::Blocks, the step out command can be accessed via Debug menu > Step out, or by pressing the ctrl-F7 shortcut combo.

Let's take a look at an example of this using the same program as above:

Step into the program until you are inside function printValue, with the execution marker on line 4.

Then choose step out. You will notice the value 5 appears in the output window, and the debugger returns control to you after the function has terminated (on line 10).

This command is most useful when you've accidentally stepped into a function that you don't want to debug.

A step too far

When stepping through a program, you can normally only step forward. It's very easy to accidentally step past (overstep) the place you wanted to examine.

If you step past your intended destination, the usual thing to do is stop debugging and restart debugging again, being a little more careful not to pass your target this time.

Step back

Some debuggers (such as Visual Studio Enterprise Edition and GDB 7.0) have introduced a stepping capability generally referred to as step back or reverse debugging. The goal of a step back is to rewind the last step, so you can return the program to a prior state. This can be useful if you overstep, or if you want to re-examine a statement that just executed.

Implementing step back requires a great deal of sophistication on the part of the debugger (because it has to keep track of a separate program state for each step). Because of the complexity, this capability isn't standardized yet, and varies by debugger. As of the time of writing (Jan 2019), neither Visual Studio Community edition nor the latest version of Code::Blocks support this capability. Hopefully at some point in the future, it will trickle down into these products and be available for wider use.


3.7 -- Using an integrated debugger: Running and breakpoints
Index
3.5 -- More debugging tactics

128 comments to 3.6 — Using an integrated debugger: Stepping

  • KK

    Hello everyone

    Shift+F11 does not work for Visual Studio on my project.

    What can i do for it?

    Many thanks

  • ethano

    Recommended to add (For Xcode users (macos). Something like:
    "On Xcode, you must add breakpoints before you debug. You click on the number next to the line to do that. Then, you Run (cmd + R) the program and not do any other build types, as they ignore breakpoints. This also executes the code as a program, so it will output any code that you have in it. (Ex. if you don't put a breakpoint before

    it will write "Hi!" in the terminal.)"

  • David

    Absolutely brilliant. I can see I'm going to be making a lot of use of this!

  • karna bc

    #define max 10
    int main()
    {
    char a[max];
    int total=1;
    char ch;
    for(int i=0;i
    {
    cin>>a[i];
    total=total*a[i];
    cout<<”Do you want to add?\n”;
    cin>>ch;
    if(ch==’n’)
    break;
    }
    for(int i=0;i
    cout<
    cout<
    return 0;
    }

    solve error

    • nascardriver

      Hi Karna!

      Please use code tags, your code is incomplete.
      What's the error message you're getting?

      Don't use 'using namespace'.
      Prefer constexpr over macros.

      • karna bc

        Q..For this code snippet, identify the conditions under which errors occur/code fails to act as expected.
        #define max 10
        int main()
        {
        char a[max];
        int total=1;
        char ch;
        for(int i=0;i
        {
        cin>>a[i];
        total=total*a[i];
        cout<<”Do you want to add?\n”;
        cin>>ch;
        if(ch==’n’)
        break;
        }
        for(int i=0;i
        cout<
        cout<
        return 0;
        }

        please solve this

  • Eddie

    Hi! For some reason when I choose 'Step into' while I am on

    it never goes into the function, it just prints the value into the console and then goes to

    . I understand everything you wrote I just wonder if there is a reason for this?

    Thank you!

    Edit: I tried it a few more times and then it just worked, weird.. Thank either way! :)

    • karna bc

      please sove this fast sir

      #define max 10
      int main()
      {
      char a[max];
      int total=1;
      char ch;
      for(int i=0;i
      {
      cin>>a[i];
      total=total*a[i];
      cout<<”Do you want to add?\n”;
      cin>>ch;
      if(ch==’n’)
      break;
      }
      for(int i=0;i
      cout<
      cout<
      return 0;
      }

      please solve this

  • Dear Teacher, please let me the question: In "Conclusion" you say: "Congratulations, you now know all of the major ways to make the debugger move through your code". How do you know that I know all that? Regards.

  • Joe

    Hello Alex, nascardriver

    I am having an issue with debugging.  

    For fun I made my main program run on a do/while loop to run a menu to be able to run all programs I have written so far.  
    Now as I attempt to debug on of the programs which lives in its own file, I am constantly taken to main, and when I attempt to run
    the buggy program it will not let me into the file to run it statement by statement to find where I am having my issue.
    I have tried the step in, step out and step over but it will not let me get past the loop in main.  should I temporarily terminate the loop to debug?

    Also if you do not mind, I would like to go ahead and ask you what I did wrong with this code that causes windows to terminate my program.  It is an attempt to dynamically allocate a string array to enter in a string.  It looks right and compiles fine without issue, but when it is called it will initiate with the cin call but it terminates with a windows error before I can proceed.

    That should be everything you need to run it.  

    Thank you for your help.

    • nascardriver

      Hi Joe!

      I can't help you with your debugger problem. Which IDE are you using?

      @sizeof doesn't return the length of a string. It returns the size of the specified data type/variable. You need

      Line 15: @string is of length @value6 so there is no index at @value6. You need

      or

      Your variables have bad names.

      • Joe

        Thank you nascardriver,

        I attempted again to run the code but it is still causing an error and being shutdown by windows.

        I am using visual studios 2017.

        I commented out line 15 and the for each loop and instead ran a regular for loop to cout the elements.

        An update while I was writing.  It seems there was still input in the buffer.  So that caused the crashing.  I added to my
        getLine() function a cin.ignore to clear the buffer and it is running now.  

        I am still having an issue with why my input is not being assigned to my array.  But at the least it has stopped
        crashing.

  • varad

    where is the continue command in visual studio 2017 while debugging ?

  • Andrew

    I would just like to take this moment to thank you Alex and all the other helpful on this website for helping not just me but everyone learn how to code.

  • Dear Teacher, please let me ask your help. I tried debugging with Code::Blocks 17.12 but failed. Problem is Settings > Debugger > Common > GDB/CDB debugger. I created path for gdb.exe and deleted Default according to an answer at Stack Overflow. Eventually after clicking Debug > Step into, a wxWidgets appears saying: Unknown option 'nx'. Thanks in advance. Regards.

    • Alex

      Hey Georges,

      I'm unable to assist you with this, as this appears to be a Code::Blocks specific configuration issue. Your best bet is to use Google search to see if you can find someone who has had the same problem.

      • Dear Teacher, please accept my many thanks for you replied and for your assistive answer. I did that with words "code blocks option 'nx'", and from resauts I chose "Images for code blocks option 'nx'". Then first image > click on image > http://wiki.codeblocks.org/index.php/MinGW_installation > 2.1 Installation > I followed instructions. Indeed in Debugger settings I configured "Default" (without quotes) and deleted gdb.exe I had added according to Stack Overflow suggestion.  If you do not configure gdb.exe, default setting is Default. Eventually everything is okay.  Regards.

  • Tij

    The step into and step over is different, but not as it is described in this text. Step over can still execute the statement in the function.

    • Alex

      > Like "Step into", The Step over command executes the next line of code. If this line is a function call, "Step over" executes all the code in the function...

      Seems pretty clear to me that step over executes the statements in the function. What am I missing?

  • Josh

    Hi Alex,

    When I tried to execute the step in command, I received the following error:
    ERROR: You need to specify a debugger program in the debuggers's settings.
    (For MinGW compilers, it's 'gdb.exe' (without the quotes))
    (For MSVC compilers, it's 'cdb.exe' (without the quotes))

    How do I specify a debugger program?

    Thanks

  • Michael

    Hey Alex,

    When I'm using step into, it will step through my program, but when it comes back out to main() and is running the "std::cout << "The sum of 3 and 4 is " << add(3, 4) << std::endl;" line, it will jump through all of these library files without outputting that code in the console window that opens up. For example, it will step through functions in "ostream", "iosfwd", "xiosbase", and a bunch of other files before it tries to read a file that is non-existent and errors out. None of this happens when I run my code normally.

    Any thoughts on why this is happening?

    Thanks,
    Michael

    • Alex

      That code is the code that implements std::cout and the << operator. As soon as you enter a standard library function, you should step out to return back to the caller.

  • Santosh Ujjwal

    Sir, what is the difference in function between "Run to Cursor" and "Breakpoint". They both seem to serve the same purpose of running up to a particular line of code after which we want to look carefully.

    • Alex

      The two functions are similar. Breakpointing code will always cause the debugger to stop on that line (stopping there multiple times if relevant). Run to cursor causes the debugger to run until the current line is encountered. It's like using a temporary breakpoint on the currently line. Run to cursor is really a convenience command.

  • My dear Teacher,
    Please let me ask you add a paragraph about breakpoints with code blocks, because with them breakpoints behave different than with visual studio.
    With regards and friendship

  • My dear c++ Teacher,
    Please let me say I can not understand "Choose “Step over” this time (this will execute this statement without stepping into the code for operator <<)."
    How is that statement "std::cout << nValue;" be executed without operator "<<" be executed?
    With regards and friendship
    Georges Theodosiou

  • Rohit

    plz help me to debud a program in code block

  • hardik kalra

    man plz help me !

    When I use step into or use any of the debugging feature in code blocks 16.01 IDE, no console output window appears just a message comes in the log window that debugging finished with status 1.

    ALEX, Plz Help Me Man.

  • My dear c++ Teacher,
    Please let me a suggestion:
    In "Step into" section after "Visual Studio does not, so if you’re using Visual Studio, choose “Stop Debugging” from the debug menu. This will terminate your debugging session."
    add: "if you continue click "step into", another .cpp file will open and yellow arrow will indicate some line in it. You must close this file and click “Stop Debugging”".
    Also in the "Run" section you say:
    "If you have been following along with the examples, you should now be inside the printValue() function. Choose the run command, and your program will finish executing and then terminate."
    But visual studio has not "run" command. "Continue" command (in Debug menu) and "Run To Cursor" in menu after right click with mouse pointer on a line do this job. Problem is that console window (the black one) disappears quickly and you can not see number 5.
    With regards and friendship.

  • Samuel

    Note to Visual Studio 2017 users: The "run to cursor" function doesn't exist in the debug menu, but a green button pops upp to the left of a line when you highlight it during debuging

  • My dear c++ teacher,
    Please let me send you my last comment for today.
    1. In templates you have "PrintValue(int nValue)", capital first letter.
    2. Between 2nd and 3rd templates and below 3rd you state "is the call to printValue()" and "the printValue() code", and "opening brace of printValue()". My understading is that you mean: function definition "void printValue(int nValue)", and that "printValue()" is function call.
    Bonne journée.
    With regards and friendship.

  • My dear c++ Teacher,
    Please let me say you that in text between 2nd and 3rd template you state: "Because printValue() WAS a function call, we “Step into” the function ...". According to my bad english it means: "printValue() is NOT any more function call".
    With regards and friendship.

  • My dear c++ Teacher,
    Please let me again ask your help for always you help your last disciple Georges Theodosiou.
    How can I do "step into" with Dev c++ 5.11?
    With regards and friendship.

    • Alex

      I am not familiar with dev c++ 5.11 so I am unable to advise you on this. I am unsure if it applies to version 5.11, but the following document may be helpful: http://eilat.sci.brooklyn.cuny.edu/cis1_5/HowToDebug.htm.

      • My dear c++ Teacher,
        Please let me express my gratitude for you replied my comment (my dear dsp Teacher Mr. Richard Lyons snobs me, he teaches me only by his book) and for suggested me a good document. It applies to version 5.11 but with some differences in names. For example instead of "next step" this version has "next line". Anyway it is helpful.
        With regards and friendship.

      • My dear c++ Teacher,
        Please let me say that as it is clear from the document you suggested me, debugging with Dev-C++ 5.11 is different than with Visual Studio.
        Before clicking "Next line" (step into) I have to check (by clicking) breakpoint. When I click (set breakpoint) on line 1 (#include <iostream>) and then click "Debug", arrow (blue) appears on line 5 (std::cout << nValue;). When next I click "Next line", console window outputs "5", and arrow goes to line 6. When I click again "Next line" arrows goes to line 11 "return 0;" and after one more click on "Next line" it goes to line 12, end of program.
        Now if I close file main.cpp and open it again, and set breakpoint on line 8 (int main()), and click "Debug", arrows goes to line 10 (printValue(5);). If then click on "Next line" console window outputs "5", and arrows goes to line 11, and after one more click on "Next line" it goes to line 12.
        So, arrow never goes from function call: printValue(5) to function definition: void printValue(int nValue).
        With regards and friendship.

  • My dear c++ Teacher,
    Please let me ask you in sentence "step into enters ..." type "step into" with bold letters so your non American disciples easy understand it is subject of the verb "enters".
    With regards and friendship.

  • My dear c++ Teacher,
    Please let me say you what two compilers output for first program, number divided by zero. Compiler
    D-C++ 5.11   throws template: "Project1.exe a cessé foctionner" that is: "Project1.exe does not function any more". Compiler
    https://www.tutorialspoint.com/compile_cpp_online.php   outputs: "Floating point exception (core dumped)".
    With regards and friendship.

  • Ian

    I'm using Code Blocks 16.01 on Ubuntu 16.04 and I cannot get the 5 to print in the debugging window. By default Code Blocks launches xterm but stepping into and moving to next line does not display any value in the xterm console as shown:

    http://imgur.com/dEf6cWK

    Some forum posts on the Code Blocks forum and other places suggest changing some settings. For example, changing from xterm to gnome-terminal. However I have the exact same results:

    http://imgur.com/pKQgQzK

    I initially thought it was related to the message I see "warning: GDB: Failed to set controlling terminal: Operation not permitted", but multiple threads on the Code Blocks forums imply that this is a cosmetic issue and should have no effect on debugging functionality.

    I have installed Code Blocks on a machine running Windows 10 and I am able to see the "5" value in the debugging window. This seems to be unique to either the the configuration of Ubuntu or of Code Blocks on this machine, however there is nothing I know of that has been modified.

    Could someone please assist me with fixing this issue?

    Thanks in advance,
    Ian

    • Ian

      I was able to resolve this issue by using std::endl

      If you are having trouble getting the debugger window to show anything on linux, I would check if the following works:

  • My dear c++ Teacher,
    Please let me say some problems I got using Code::Blocks 16.01.
    1st: When first I choose "step into", yellow arrow appears not to the left of the opening brace of main(), but of the  printValue(5);.
    2nd: When for second time I choose "step into", yellow arrow appears not to the left of the opening brace of printValue(int nValue), but of the std::cout << nValue;.
    Also let me following question:
    You state: "Choose “Step over” this time (this will execute this statement without stepping into the code for operator <<). Because the cout statement has now been executed, you should see that the value 5 appears in the output window."
    Yes, value 5 appears in the output window, but how "step over" executes this statement without stepping into the code for operator <<? My understanding is that this operator is including in this statement, then if operator is ignored, statement should not be executed.
    With regards and friendship.

    • Alex

      I wrote the article using Visual Studio 2015 -- some other debuggers might do things slightly differently. So your first and second point are fine.

      Regarding your third point, step over does not ignore the statement -- it executes the statement without stepping into any functions, allowing you to skip past function calls you're not interested in debugging.

  • Garry E

    Alex:
    Using Visual Studio 2015. Debugged printValue sketch and everything in tutorial went according
    to plan up to the point of entering "Step out".After that a new screen with over 200 lines
    of code popped up. My original screen was titled ConsoleApplication7.cpp . The new one was simply called
    Miscellaneous. The cursor was at line 64 in this program. After fumbling around a bit I found that if I
    repeatedly clicked "Step into" the cursor walked down the page and eventually ConsoleApplication7 came
    back. The figure 5 did appear in the console output window after "Step out" was applied. After restoring
    the ConsoleApplication7 screen with "Step into" clicks the output screen was blank. Is there an easy
    answer?

    Garry E

    • Alex

      Could have been something from the C++ standard library. Sometimes the debugger will pop into there and walk through all kinds of crazy obtuse code before returning back to your code. When that happens, an additional step out normally returns you to your code.

  • OA

    For xCode 7 Users:

    My debug menu in xCode 7 was greyed out, this YouTube tutorial was a good explanation:

    https://www.youtube.com/watch?v=VsenB1fTgXk

  • hp

    Hi i still do not understand how  5 - 3 = 2, how come it is 8 as you said above?

    • Alex

      The function is named add(), so clearly the intent is to add the numbers, not subtract them. The add() function has a typo where the minus operator is being used instead of the plus operator, so the result of add(5,3) is 2 instead of the expected 8.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]