Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
C++ System Programming Cookbook

You're reading from   C++ System Programming Cookbook Practical recipes for Linux system-level programming using the latest C++ features

Arrow left icon
Product type Paperback
Published in Feb 2020
Publisher Packt
ISBN-13 9781838646554
Length 292 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Onorato Vaticone Onorato Vaticone
Author Profile Icon Onorato Vaticone
Onorato Vaticone
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Getting Started with System Programming 2. Revisiting C++ FREE CHAPTER 3. Dealing with Processes and Threads 4. Deep Dive into Memory Management 5. Using Mutexes, Semaphores, and Condition Variables 6. Pipes, First-In First-Out (FIFO), Message Queues, and Shared Memory 7. Network Programming 8. Dealing with Console I/O and Files 9. Dealing with Time Interfaces 10. Managing Signals 11. Scheduling 12. Other Books You May Enjoy

Using GDB to debug a program

Debugging is the process of identifying and removing errors from software systems. The GNU/Linux operating system has a standard de facto tool (that is, not part of any standard, but used by almost anybody in the Linux world) called GDB. The GDB version installed on this book's Docker is version 8.2.91. Of course, there are graphical tools that can use GDB under the hood, but GDB on Linux is the way to go for its reliability, simplicity, and speed. In this recipe, we will debug the software we've written in the previous recipe.

How to do it...

In order to use some of the GDB commands, we need to modify the previous program and add some variables in it:

  1. Open a shell and modify the hello.cpp file by typing in the following code:
 #include <iostream>
int main()
{
int x = 10;
x += 2;
std::cout << "Hello World! x = " << x << std::endl;
return 0;
}

This is a very simple program: take a variable, add 2 to it, and print the result.

  1. Let's make sure that the program is compiled by typing the following command:
root@bffd758254f8:~/Chapter1# make
g++ -c hello.cpp
g++ -o hello hello.o
  1. Now that we have the executable, we will debug it. From the command line, type gdb hello:
root@bffd758254f8:~/Chapter1# gdb hello
GNU gdb (Ubuntu 8.2.91.20190405-0ubuntu3) 8.2.91.20190405-git
Copyright (C) 2019 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 hello...
(No debugging symbols found in hello)
(gdb)
  1. As you can see, the last line says (No debugging symbols found in hello). GDB doesn't have to debug symbols to debug the program, so we have to communicate to the compiler that the debug symbols are to be included during the compilation. We have to quit the current session; to do this, type q (Enter]. Then, edit the makefile, and add the -g option to the g++ compiler section (the hello.o target):
CC = g++
all: hello
hello: hello.o
${CC} -o hello hello.o
hello.o: hello.cpp
$(CC) -c -g hello.cpp
clean:
rm hello.o hello
  1. Let's run it again, but, first, we have to rebuild the application with the make command:
root@bcec6ff72b3c:/BOOK/chapter1# gdb hello
GNU gdb (Ubuntu 8.2.91.20190405-0ubuntu3) 8.2.91.20190405-git
Copyright (C) 2019 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 hello...
(No debugging symbols found in hello)
(gdb)

We're ready to debug it. A debug session typically includes setting breakpoints, watching the content of variables, setting watchpoints, and many others. The next section will show the most common debug commands.

How it works...

In the previous section, we have seen the steps necessary to create a program and a makefile. In this section, we'll learn how to debug the Hello World! program we developed.

Let's start by visualizing the code we're going to debug. We do this by running the l command (short for list):

(gdb) l
1 #include <iostream>
2 int main()
3 {
4 int x = 10;
5 x += 2;
6 std::cout << "Hello World! x = " << x << std::endl;
7 return 0;
8 }

We have to set a breakpoint. To set a breakpoint, we run the b 5 command. This sets a breakpoint to the code line number 5 in the current module:

(gdb) b 5
Breakpoint 1 at 0x1169: file hello.cpp, line 5.
(gdb)

It's time to run the program now. To run a program, we type the r command. This runs the hello program we started with GDB:

(gdb) r
Starting program: /root/Chapter1/hello

Once started, GDB will automatically stop at any breakpoint hit by the process flow. In this case, the process runs, and then stops at line 5 of the hello.cpp file:

Breakpoint 1, main () at hello.cpp:5
5 x += 2;

To proceed step by step, we run the n command (that is, step over) on GDB. This executes the current visualized line of code. A similar command is s (step into). If the current command is a function, it steps into the function:

(gdb) n
6 std::cout << "Hello World! x = " << x << std::endl;
the 'n' command (short for next) execute one line. Now we may want to check the content of the variable x after the increment:

If we need to know the content of a variable, we run the p command (short for print), which prints the content of a variable. In this case, as expected, x = 12 gets printed:

(gdb) p x
$1 = 12

Now, let's run the program until the end (or until the next breakpoint, if set). This is done with the c command (short for continue):

(gdb) c 
Continuing.
Hello World! x = 12
[Inferior 1 (process 101) exited normally]
(gdb)

GDB really acts as an interpreter by letting the programmer step the program line by line. This helps the developer to troubleshoot problems, see the content of variables at runtime, change the status of variables, and more.

There's more...

GDB has a lot of very useful commands. In the following chapters, GDB will be explored more. There are four more commands to show here:

  1. s: Short for step. If called on a method, it steps into it.
  2. bt: Short for backtrace. Prints the call stack.
  3. q: Short for quit. Use to exit GDB.
  4. d: Short for delete. It removes a breakpoint. For example, d 1 removes the first breakpoint set.
The main page of the GNU GDB Project can be found here: https://www.gnu.org/software/gdb. More detailed information can be found on the man dbg man pages and online. You can also refer to Using GDB: A Guide to the GNU Source-Level Debugger, by Richard M. Stallman and Roland H. Pesch.
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime