Detailed Methods and Techniques for GDB Debugging on Linux

1. Introduction to GDB

GDB is a powerful command-line debugging tool released by the GNU open-source organization for UNIX/LINUX operating systems. For a C/C++ programmer working on Linux, GDB is an essential tool;

2. GDB Usage Process

Here, we will use a C program for basic demonstration, and the same applies to C++ programs;

1. Start GDB

Compile a test program, where -g indicates that it can be debugged, with the command as follows:

gcc -g test.c -o test

Start GDB with the command as follows:

gdb test 

gdb -q test // This indicates not to print GDB version information, providing a cleaner interface;

The test is as follows:

root@ubuntu:/home/eit/c_test# gdb test

GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7

Copyright (C) 2014 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type “show copying”

and “show warranty” for details.

This GDB was configured as “x86_64-linux-gnu”.

Type “show configuration” for configuration details.

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>.

Find the GDB manual and other documentation resources online at:

<http://www.gnu.org/software/gdb/documentation/>.

For help, type “help”.

Type “apropos word” to search for commands related to “word”…

Reading symbols from test…done.

(gdb) q

root@ubuntu:/home/eit/c_test# gdb -q test

Reading symbols from test…done.

(gdb)

GDB has started successfully!

2. View Source Code

list (abbreviated as l): View the source code, default shows 10 lines, press Enter to continue viewing the rest.

The test is as follows:

(gdb) list

9#define MAX_SIZE

10

11int main()

12{

13 int i,fd,size1 ,size2 ,len;

14 char *buf = “helo!I’m liujiangyong “;

15 char buf_r[15];

16 len = strlen(buf);

17 fd = open(“/home/hello.txt”,O_CREAT | O_TRUNC | O_RDWR,0666);

18 if (fd<0)

(gdb)

19 {

20 perror(“open :”);

21 exit(1);

22 }

23 else

24 {

25 printf(“open file:hello.txt %d\n”,fd);

26 }

27 size1 = write(fd,buf,len);

28 if (fd<0)

(gdb)

29 {

30 printf(“write error;”);

31

32 }

33 else

34 {

35 printf(“Length written: %d\nContent written: %s\n”,size1,buf);

36

37 }

38 lseek(fd,0,SEEK_SET);

(gdb)

39 size2 = read(fd,buf_r,12);

40 if (size2 <0)

41 {

42 printf(“read error\n”);

43 }

44 else

45 {

46 printf(“Length read: %d\nContent read: %s\n”,size2,buf_r);

47 }

48 close(fd);

(gdb)

49

50

51}

(gdb)

Line number 52 out of range; write.c has 51 lines.

(gdb)

3. Run Program

run (abbreviated as r): Run the program until it encounters an end or a breakpoint waiting for the next command;

The test is as follows:

(gdb) r

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /home/eit/c_test/test

open file:hello.txt 3

Length written: 22

Content written: helo!I’m liujiangyong

Length read: 12

Content read: helo!I’m liu

[Inferior 1 (process 19987) exited normally]

(gdb)

4. Set Breakpoints

break (abbreviated as b): Format b line number, set a breakpoint at a certain line;

info breakpoints: Display breakpoint information

Num: Breakpoint number

Disp: Whether the breakpoint is valid after execution once kep: valid dis: invalid

Enb: Whether the current breakpoint is valid y: valid n: invalid

Address: Memory address

What: Location

(gdb) b 5

Breakpoint 3 at 0x400836: file write.c, line 5.

(gdb) b 26

Breakpoint 4 at 0x4008a6: file write.c, line 26.

(gdb) b 30

Breakpoint 5 at 0x4008c6: file write.c, line 30.

(gdb) info breakpoints

Num Type Disp Enb Address What

3 breakpoint keep y 0x0000000000400836 in main at write.c:5

4 breakpoint keep y 0x00000000004008a6 in main at write.c:26

5 breakpoint keep y 0x00000000004008c6 in main at write.c:30

(gdb)

5. Step Execution

Use continue, step, next commands

The test is as follows:

(gdb) r

Starting program: /home/eit/c_test/test

Breakpoint 3, main () at write.c:12

12{

(gdb) n

14 char *buf = “helo!I’m liujiangyong “;

(gdb)

16 len = strlen(buf);

(gdb)

17 fd = open(“/home/hello.txt”,O_CREAT | O_TRUNC | O_RDWR,0666);

(gdb) s

open64 () at ../sysdeps/unix/syscall-template.S:81

81../sysdeps/unix/syscall-template.S: No such file or directory.

(gdb)

main () at write.c:18

18 if (fd<0)

(gdb)

25 printf(“open file:hello.txt %d\n”,fd);

(gdb)

__printf (format=0x400a26 “open file:hello.txt %d\n”) at printf.c:28

28printf.c: No such file or directory.

(gdb) c

Continuing.

open file:hello.txt 3

Breakpoint 4, main () at write.c:27

27 size1 = write(fd,buf,len);

(gdb)

Continuing.

Length written: 22

Content written: helo!I’m liujiangyong

Length read: 12

Content read: helo!I’m liu

[Inferior 1 (process 20737) exited normally]

(gdb)

6. View Variables

Use print, whatis commands

The test is as follows:

main () at write.c:28

28 if (fd<0)

(gdb)

35 printf(“Length written: %d\nContent written: %s\n”,size1,buf);

(gdb) print fd

$10 = 3

(gdb) whatis fd

type = int

(gdb)

7. Exit GDB

Use the quit command to exit GDB:

(gdb) r

Starting program: /home/eit/c_test/test

open file:hello.txt 3

Length written: 22

Content written: helo!I’m liujiangyong

Length read: 12

Content read: helo!I’m liu

[Inferior 1 (process 20815) exited normally]

(gdb) q

root@ubuntu:/home/eit/c_test# 

continue (abbreviated as c): Continue executing the program until the next breakpoint or end;

next (abbreviated as n): Step through the program, but skip over functions without entering them;

step (abbreviated as s): Step through the program, entering functions when encountered;

until: When you are tired of stepping through a loop, this command can run the program until exiting the loop;

until + line number: Run to a specific line, not just to exit a loop;

finish: Run the program until the current function completes and returns, printing information like the stack address, return value, and parameter values;

call function (parameter): Call a visible function in the program and pass “parameter”, e.g., call gdb_test(55);

quit: abbreviated as q, exit GDB;

3. Basic GDB Commands

1. Run Command

run: abbreviated as r, its function is to run the program. When it encounters a breakpoint, the program will stop at the breakpoint, waiting for the user to input the next command.

continue (abbreviated c): Continue executing until the next breakpoint (or program ends)

next: (abbreviated n), step through the program, but do not enter the function body when encountering a function call; the main difference between this command and step is that step will enter user-defined functions, while next will directly call the function without entering the body.

step (abbreviated s): Step debug, if there is a function call, it will enter the function; unlike command n, n does not enter the called function.

until: When you are tired of stepping through a loop, this command can run the program until exiting the loop.

until + line number: Run to a specific line, not just for exiting the loop.

finish: Run the program until the current function completes and returns, printing information like the stack address, return value, and parameter values.

call function (parameter): Call a visible function in the program and pass “parameter”, e.g., call gdb_test(55)

quit: abbreviated as q, exit GDB

2. Set Breakpoints

break n (abbreviated b n): Set a breakpoint at line n

(can include code path and code name: b OAGUPDATE.cpp:578)

b fn1 if a>b: Set conditional breakpoint

break func (break abbreviated as b): Set a breakpoint at the entry of function func(), e.g., break cb_button

delete breakpoint number n: Delete the nth breakpoint

disable breakpoint number n: Pause the nth breakpoint

enable breakpoint number n: Enable the nth breakpoint

clear line number n: Clear the breakpoint at line n

info b (info breakpoints): Display the current program’s breakpoint settings

delete breakpoints: Clear all breakpoints:

3. View Source Code

list: abbreviated as l, its function is to list the source code of the program, default shows 10 lines each time.

list line number: Will display the current file’s code surrounding the “line number” as the center, e.g., list 12

list function name: Will display the source code of the function where “function name” is located, e.g., list main

list: Without parameters, will continue to output the content from the last list command.

4. Print Expressions

print expression: abbreviated as p, where “expression” can be any valid expression currently being tested in the program being debugged. For example, if debugging a C program, then “expression” can be any valid C expression, including numbers, variables, or even function calls.

print a: Will display the value of integer a

print ++a: Will increment the value in a by 1 and display it

print name: Will display the value of string name

print gdb_test(22): Will call the gdb_test() function with integer 22 as the parameter

print gdb_test(a): Will call the gdb_test() function with variable a as the parameter

display expression: Will be very useful during step execution. After setting an expression with the display command, it will output the set expression and value after each step instruction. For example: display a

watch expression: Set a watchpoint. Once the value of the “expression” being watched changes, GDB will forcibly terminate the program being debugged. For example: watch a

whatis: Query variable or function

info function: Query function

Extended info locals: Display all variables on the current stack page

5. View Running Information

where/bt: Current running stack list;

bt backtrace shows the current call stack

up/down changes the depth of stack display

set args parameter: Specify parameters at runtime

show args: View the set parameters

info program: To see whether the program is running, the process number, and the reason for being paused.

6. Split Window

layout: Used to split the window, allowing you to view the code while testing:

layout src: Display the source code window

layout asm: Display the disassembly window

layout regs: Display source code/disassembly and CPU register window

layout split: Display source code and disassembly window

Ctrl + L: Refresh window

7. CGDB Powerful Tool

CGDB’s main function is to synchronize the display of code during debugging, which undoubtedly increases debugging convenience and improves debugging efficiency. Its interface is similar to vi, conforming to the habits of UNIX/Linux developers; if you are familiar with GDB and vi, you can almost immediately use CGDB.

8. Summary of Common GDB Debugging Commands

Detailed Methods and Techniques for GDB Debugging on Linux

4. Conclusion

In summary, mastering the use of GDB/CGDB is essential for developing programs on Linux. Its power goes far beyond this; using it in program debugging will improve our debugging efficiency. Of course, the functions and techniques of GDB are not limited to this, so explore and learn more.

Leave a Comment