Debugging C++ Programs Using GDB in Command Line (Part Two)

If you haven’t read the previous article, I suggest you check it out: Debugging C++ Programs Using GDB in Command Line (Part One)

This article supplements the GDB debugging that wasn’t finished last time.

I Want to Install GDB on Linux

Okay, I downgraded the Linux distribution running on WSL from <span>24.04</span> to <span>22.04</span>, and as a result, <span>gcc</span> and <span>gdb</span> were all installed successfully.

sudo apt install gcc
sudo apt install gdb

Debugging C++ Programs Using GDB in Command Line (Part Two)This indicates that it was indeed a problem with <span>24.04</span>, but I am not quite sure why. It might be because <span>22.04</span> installs <span>gcc11</span> by default, while <span>24.04</span> installs <span>gcc14</span> by default. So if you have similar issues, you can try downgrading.

Printing/Tracking Variables

We set a breakpoint at line 21 of the function:

Thread 1 hit Breakpoint 1, main () at testOP.cpp:21
21          S s2{1};

At this point, run and use <span>p variable_name</span> to print the variable’s name.

(gdb) p s2
$1 = {num = 8}

Since <span>s2</span> has not been assigned a value yet, what is printed is the residual data in memory. After running one more line, <span>s2</span> will have a value:

(gdb) n
22          cout &lt;&lt; (s1 == s2) &lt;&lt; endl;
(gdb) p s2
$7 = {num = 1}

Using <span>display variable_name</span> can track the variable, and its value will be printed every time an operation is executed:

(gdb) b 21
Breakpoint 3 at 0x7ff619ac146e: file testOP.cpp, line 21.
(gdb) r   
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 4288.0x2c34]
[New Thread 4288.0x67ec]
[New Thread 4288.0x3718]

Thread 1 hit Breakpoint 3, main () at testOP.cpp:21
21          S s2{1};
(gdb) display s1
1: s1 = {num = 1}
(gdb) n
22          cout &lt;&lt; (s1 == s2) &lt;&lt; endl;
1: s1 = {num = 1}

It is important to note that the <span>display</span> operation needs to be executed while the program is running; otherwise, it will not find the symbol:<span>No symbol "s1" in current context.</span>

<span>undisplay variable_number</span> can cancel tracking, for example, the number for the above <span>s1</span> is 1 (the number before it).

(gdb) n
22          cout &lt;&lt; (s1 == s2) &lt;&lt; endl;
1: s1 = {num = 1}
(gdb) undisplay 1
(gdb) n
1
23      }

Printing Function Stack

<span>bt</span> can print the function stack.

(gdb) bt
#0  main () at testOP.cpp:21
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) n
Program not restarted.
(gdb) s
S::S (this=0x5ffec8, num=1) at testOP.cpp:8
8           S(int num) : num(num) {};
(gdb) bt
#0  S::S (this=0x5ffec8, num=1) at testOP.cpp:8
#1  0x00007ff619ac147f in main () at testOP.cpp:21

For example, after entering the constructor of <span>S</span>, this function replaces the main function as the new stack top.

Assignment

You can use <span>set var variable_name=value</span> to assign a value to a variable.

(gdb) display s1
2: s1 = {num = 1}
(gdb) set var s1=2
(gdb) n
22          cout &lt;&lt; (s1 == s2) &lt;&lt; endl;
2: s1 = {num = 2}

Generally speaking, this assignment needs to follow C++ syntax, such as:

  1. Ensure the variable can be assigned; it cannot be const and cannot be invisible in the current scope — for example, if GDB hasn’t run into the function yet, it can’t assign a value to a local variable inside the function, etc.
  2. Cannot assign a total value to a structure with multiple members, but you can use curly braces according to C++ syntax.

In summary, assignment operations that cannot be performed in code cannot be performed with <span>set var</span> either.

Enable/Disable Breakpoints

<span>disable b</span> makes all breakpoints ineffective.

(gdb) info b
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep y   0x00007ff619ac145d in main() at testOP.cpp:20
(gdb) disable b
(gdb) info b   
Num     Type           Disp Enb Address            What
3       breakpoint     keep n   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep n   0x00007ff619ac145d in main() at testOP.cpp:20

<span>enable b</span> makes all breakpoints effective.

(gdb) enable b
(gdb) info b  
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep y   0x00007ff619ac145d in main() at testOP.cpp:20

<span>disable b number</span> makes a breakpoint ineffective.<span>enable b number</span> makes a breakpoint effective.

Jump to Specific Line Number

<span>until line_number</span> jumps to the specified location, executing the code in the interval.

(gdb) b 20
Breakpoint 5 at 0x7ff619ac145d: file testOP.cpp, line 20.
(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 25504.0x5ab0]
[New Thread 25504.0x559c]
[New Thread 25504.0x550c]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) until 22
main () at testOP.cpp:22
22          cout &lt;&lt; (s1 == s2) &lt;&lt; endl;
2: s1 = {num = 1}

This directly executes to line 22 of the code.

Finish Function

<span>finish</span> executes until the current function returns.

(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 17196.0x1850]
[New Thread 17196.0x2fbc]
[New Thread 17196.0x3ab0]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) s
S::S (this=0x5ffecc, num=1) at testOP.cpp:8
8           S(int num) : num(num) {};
(gdb) finish
Run till exit from #0  S::S (this=0x5ffecc, num=1) at testOP.cpp:8
main () at testOP.cpp:21
21          S s2{1};
2: s1 = {num = 1}

Using <span>step</span> to step into the constructor, and <span>finish</span> to jump out of the function.

Jump to Next Breakpoint

<span>c</span> runs directly from one breakpoint to the next.

(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 2180.0x227c]
[New Thread 2180.0x55c4]
[New Thread 2180.0x6080]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) c
Continuing.

Thread 1 hit Breakpoint 6, main () at testOP.cpp:21
21          S s2{1};
2: s1 = {num = 1}

GDB hits the first breakpoint at line 20, and then we jump directly to line 21 where the next breakpoint is.

Leave a Comment