GDB Tips and Tricks #5: The Display Command

Once of the cool things about debugging with IDEs is that they typically give you a nice mechanism to watch the changing state of variables as you step through code. In Visual Studio, for example, you can right click on a variable name and select “Add Watch” from the menu. The variable name and its current value will be shown in a little “Watch” window. You can watch as many variables as you have the resources and patience for. As you step through the code, anytime the value of a watched variable changes, that change is reflected in the Watch window.

Can we do something similar in gdb? Absolutely.

The command we’re interested in is display. When gdb is told to display a variable, it’ll report that variable’s current value every time program execution pauses (e.g., stepping through the code).

Let’s see an example using the following snippet of code.

// demo.cpp
int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
 
    a = a + 1;
    b += a;
    c = a * b + c;
 
    return 0;
}

First we compile and then launch gdb.

skirk@dormouse:~$ g++ -g ./demo.cpp -o demo
skirk@dormouse:~$ gdb ./demo
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 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-pc-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 /home/skirk/demo...done.
(gdb)

Let’s now run our app, stopping at main().

(gdb) start
Temporary breakpoint 1 at 0x4004bb: file ./demo.cpp, line 3.
Starting program: /home/skirk/demo 
 
Temporary breakpoint 1, main () at ./demo.cpp:3
3	    int a = 1;

Let’s say at this point we want to display the values of variables a, b, and c as we step through the code. We can issue the display command like so.

(gdb) display a
1: a = 32767
(gdb) display b
2: b = 0
(gdb) display c
3: c = 0

After each display is executed, gdb shows the current value for the variable specified. In this example, our variables have bogus values because they haven’t been initialized yet. Let’s now step through the code and see what display does for us.

(gdb) n
4	    int b = 2;
1: a = 1
2: b = 0
3: c = 0
(gdb) n
5	    int c = 3;
1: a = 1
2: b = 2
3: c = 0
(gdb) n
7	    a = a + 1;
1: a = 1
2: b = 2
3: c = 3
(gdb) n
8	    b += a;
1: a = 2
2: b = 2
3: c = 3
(gdb) n
9	    c = a * b + c;
1: a = 2
2: b = 4
3: c = 3
(gdb) n
11	    return 0;
1: a = 2
2: b = 4
3: c = 11

Every time we step through the code, our program execution pauses and the current values of the variables we asked gdb to display are shown. As you can imagine, this can save a tremendous amount of time over, say, repeatedly using a step command followed by a print command.

It’s worth noting that the variable value information will only be displayed for variables that are currently in scope. If the variables we’re interested in are local to a function that at some point returns, those variables will no longer be displayed once they’re out of scope. However, gdb doesn’t forget about those variables. It will absolutely display them the next chance it gets. If you later step into that function again, those variables will be displayed.

When you’re no longer interested in a given variable, you can issue the undisplay command. The gotcha here is that undisplay doesn’t operate on variable names. It operates on display numbers. “Where is the display number?” you ask. It’s the number next to the “variable=value” line in the display output. In our example above, the display output for our variable c is “3: c = 11”. Note the 3 before the colon? It’s not just to pretty up the output. That’s the display number assigned to that particular variable.

You can undisplay a single display number like so.

(gdb) undisplay 1

You can also undisplay multiple display numbers at once.

(gdb) undisplay 2 3

Note that the display command shouldn’t be confused with the watch command, which serves a related purpose. The watch command works more like a smart breakpoint (these are actually called watchpoints) in that it stops program execution and displays a given variable’s value only when the value changes. The display command provides a continuous display of variables and doesn’t affect program execution at all.

Fall Foliage in Maine

A few weeks ago, I finished editing what may be my last drone video of the year. Near the beginning of October, I spent about 2 weeks filming fall foliage near my home in Durham, ME. I had hoped to have a few more days to film, but alas…a monster storm came through and took out whatever remaining leaves were left on the trees.

I didn’t have as much footage to work with as I had hoped, but I comped together what I had. The video is below.

All of the video was shot using a stock DJI Phantom 4 Advanced.

Solderless Pi Zero Headers

A while back, I got my hands on an interesting little gadget from Pimoroni – a solderless GPIO header for the Raspberry Pi Zero. If you’re working on a Pi Zero project that requires some GPIO headers and you’re not that confident in your soldering skills, this product is perfect for you!

There are two versions of the headers – one with a jig and one without. If you already have the jig, you obviously don’t need to buy another. But if this is your first time purchasing the headers, you’ll need to make sure you get the jig too.

The headers themselves are special made. They have a very precisely flared end that, when inserted into the Pi Zero, locks them into place and provide contacts to the GPIO solder pads.

“How do you actually get the pin headers into the Pi Zero?”, you ask. With the jig and some gently applied brute force.

The first thing is to insert the Pi Zero into the jig…

…Then you lay the pin headers into their holes…

…You then you place the hammer bar on top of the pin headers…

…Why do I call it the hammer bar? Because you then break out your hammer and rap it up and down the pin header bar until the header is completely and entirely seated.

Yes, that’s right – a hammer. Don’t go crazy with it, though. Be gentle. If you find that a delicate touch isn’t that effective, slowly increase the amount of force you use. And don’t hammer in one spot. Each rap should be in a different spot. Otherwise you risk damaging the pin header, or even the Pi Zero.

Once you’re finished, the pin header should be flush with the board.


Pretty neat, eh?