-
Example Code with Bugs
-
GDB Debugging Operations
-
CGDB Debugging Operations
CGDB is a frontend
for GDB
, providing a graphical interface in the terminal for debugging code (based on ncurse
), which is very convenient. Compared to GDB
, it can significantly improve efficiency.
This article will share the most basic usage of CGDB
. If this is your first time hearing about it, I strongly recommend you give it a try; you will definitely love it!
Example Code with Bugs
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef struct USER_DATA{
char data[32];
unsigned short data_len;
unsigned int flag;
}__attribute((packed));
const unsigned char * g_data = "hello";
/*
Function: Load a piece of data
Parameter 1: data[OUT]: Buffer to load data
Parameter 2: len [OUT]: Actual length of loaded data
Return value: 0-success, else-failure
*/
static int get_data(unsigned char *data, unsigned int *len)
{
assert(data && len);
memcpy((void *)data, (void *)g_data, strlen(g_data));
*len = strlen(g_data);
return 0;
}
int main(int argc, char *argv[])
{
// Create struct variable
struct USER_DATA user_data;
user_data.flag = 0xA5;
// Load data into struct variable
if (0 == get_data(user_data.data, &user_data.data_len))
{
printf("get_data ok! \n");
printf("data_len = %d, data = %s \n", user_data.data_len, user_data.data);
printf("user_data.flag = 0x%x \n", user_data.flag); // Expected value: 0xA5
}
else
{
printf("get_data failed! \n");
}
return 0;
}
Before compiling, take a look at the code. Can you find the bug
in it?
Of course, during compilation, the compiler gives a warning about the risk. Since the example code is simple, it is easy to spot.
However, in a project, if you don’t like to eliminate compilation Warning
, this bug
can be quite hidden.
Compile the test code: gcc -g test.c -o test
Since you need to use GDB
for debugging, don’t forget to add the -g
option.
GDB Debugging Operations
$ gdb ./test
(gdb) r // Execute once at full speed
(gdb) r
Starting program: /home/captain/demos_2022/cgdb/test
test start...
get_data ok!
data_len = 5, data = hello
user_data.flag = 0x0
[Inferior 1 (process 9933) exited normally]
Noticing that the value of user_data.flag
is incorrect, I decided to set a breakpoint at the line before calling get_data
and start execution from the beginning:
Check the line number of the code:
(gdb) l main
18 *len = strlen(g_data);
19 return 0;
20 }
21
22 int main(int argc, char *argv[])
23 {
24 struct USER_DATA user_data;
25 user_data.flag = 0xA5;
26 if (0 == get_data(user_data.data, &user_data.data_len))
27 {
Set a breakpoint at line 25
:
(gdb) b 25
Breakpoint 1 at 0x400771: file test.c, line 25.
Start running:
(gdb) r
Starting program: /home/captain/demos_2022/cgdb/test
Breakpoint 1, main (argc=1, argv=0x7fffffffdc58) at test.c:25
25 user_data.flag = 0xA5;
The execution stopped at the breakpoint, and the assignment statement has not been executed yet, so let’s execute it step by step:
(gdb) step
26 if (0 == get_data(user_data.data, &user_data.data_len))
At this point, print the value and address of the variable user_data.flag
:
Since we will enter the called function soon, this variable will become invisible, so we need to print it by address.
(gdb) print &user_data.flag
$1 = (unsigned int *) 0x7fffffffdb62
(gdb) print/x user_data.flag
$2 = 0xa5
At this point, the assignment is correct. Continue to execute, entering the called function get_data()
,
(gdb) step
get_data (data=0x7fffffffdb40 "n\333\377\377\377\177", len=0x7fffffffdb60) at test.c:16
16 assert(data && len);
This function has only 4
lines of code, and we execute each line step by step, printing the content of user_data.flag
variable each time.
Step to the next line at memcpy
and check if the content at the address of user_data.flag
is still: 0xa5
:
(gdb) step
17 memcpy((void *)data, (void *)g_data, strlen(g_data));
(gdb) print/x *0x7fffffffdb62
$3 = 0xa5
Continue stepping (since we don’t need to follow the internals of memcpy
and strlen
, use the next
command) and print:
(gdb) next
18 *len = strlen(g_data); // This line is about to be executed
(gdb) print/x *0x7fffffffdb62
$4 = 0xa5
(gdb) next
19 return 0;
(gdb) print/x *0x7fffffffdb62
$5 = 0x0
Problem discovered: After executing the statement *len = strlen(g_data)
, the content in the address of the variable user_data.flag
has changed.
After carefully checking the code, we can diagnose that the data type used was incorrect.
Bug Fix: The last parameter of the get_data()
function should indeed be a pointer of type unsigned short
.
The problem is solved, but looking back at the gdb
debugging process, it is still quite cumbersome: debugging instructions and code display mixed together, requiring many commands to be typed.
CGDB Debugging Operations
After starting CGDB
, the terminal window is divided into two parts: the upper part is the code window, and the lower part is the debugging window.

Press the ESC
key to enter the code window, where you can browse the code up and down, and perform a series of operations:
Spacebar: Set or cancel a breakpoint;
o: View the file where the code is located;
/ or ?: Search for strings in the code;
…
There are many convenient hotkeys:
-: Shrink the code window;
+: Expand the code window;
gg: Move the cursor to the top of the file;
GG: Move the cursor to the bottom of the file;
ctrl + b: Scroll up one page in the code;
ctrl + u: Scroll up half a page in the code;
ctrl + f: Scroll down one page in the code;
ctrl + d: Scroll down half a page in the code;
Press the i
key to return to the debugging window, entering debugging mode, where the debugging commands are almost the same as GDB
!
In other words: You can perform debugging operations while viewing the code in real-time, greatly improving efficiency.
Let’s go through the debugging process of GDB
again:
Press the ESC
key to enter the code window; if the line number in front of the code is white, it indicates the current line.
Press the j
key to move the highlighted current line down. When moving to line 25
, as shown below:

Press the spacebar to set a breakpoint at this line, and the line number turns red:

And the debugging window prints a line of information:
(gdb)
Breakpoint 1 at 0x400771: file test.c, line 25.
Press the i
key to return to the debugging operation window, then input the run command r
, and it will stop at line 25
, as shown by the green arrow:

Of course, the debugging window will also print related information:
(gdb) r
Starting program: /home/captain/demos_2022/cgdb/test
Breakpoint 1, main (argc=1, argv=0x7fffffffdc58) at test.c:25
Step step
through this assignment statement, and then print the value and address of user_data.flag
:
(gdb) print/x user_data.flag
1: /x user_data.flag = 0xa5
(gdb) print &user_data.flag
2: &user_data.flag = (unsigned int *) 0x7fffffffdb62
At this point, the assignment statement executed correctly, and the printed value also meets expectations.
Then execute the step command, entering the function get_data()
:
(gdb) step
get_data (data=0x7fffffffdb40 "n\333\377\377\377\177", len=0x7fffffffdb60) at test.c:16
At this point, the upper code window automatically enters the related code of get_data()
, as shown below:

Continue stepping, and before executing the assignment statement *len = strlen(g_data);
, print the content in the address of the variable user_data.flag
:
(gdb) print/x *0x7fffffffdb62
$2 = 0xa5
Correct! Then execute the assignment statement, and print again:
(gdb) next
(gdb) print/x *0x7fffffffdb62
$3 = 0x0
Problem discovered: After executing the statement *len = strlen(g_data)
, the content in the address of the variable user_data.flag
has changed.
Summary:
The operation process of CGDB
, although I wrote it quite verbose, is actually very smoother to use, just like chocolate!
– EOF –
Add the WeChat of the homepage manager, not just C/C++ skills +1

The homepage manager will also regularly share C/C++ development learning resources and selected technical articles on personal WeChat, and will share some interesting activities, job referrals, and how to use technology for hobby projects from time to time.
Add WeChat, open a window
1. GDB Debugging – From Beginner Practice to Principles
2. Understand in One Article | GDB Underlying Implementation Principles
3. C++ Successor? Overview of Carbon Syntax!
Follow ‘CPP Developers’
Read selected C/C++ technical articles
Likes and views are the biggest support❤️