Debugging For Beginners

This post was also published at O’Reilly Programming – you can read it here.

I read an interesting article today, called Debugging for Beginners, over at O’Reilly Programming.

You all know how much I love GDB (huh? you didn’t? seriously?), so I always like to take a look at different approaches to finding those elusive problems that plague all programmers (even those with decades of experience) from time to time.

Anyhow, I headed on over and was a little bit… disappointed. You see, Brian writes in a wonderful, readable way, about topics that concern all programmers, whatever their background. But, I found that the general focus of his article was less on how to debug (even at a higher, theoretical level), and more about how to make less mistakes.

Read moreDebugging For Beginners

GDB Prompt in Colour

Just because you can.

gdb colour prompt

Yeah, I know, why bother when you can use a nice front end like Eclipse, or DDD, or CGDB or blah blah blah.

If you just like to use it in its raw form on the command line (which, let’s face it, is the best way), you can pretty-up your GDB prompt with a really simple command.

Just load up GDB and type the following:

set prompt \033[0;32m(gdb) \033[0m

to set the prompt to a lovely green colour.

Or try this:

set prompt \033[0;34m(gdb) \033[0m

to change it to a nice, eye-catching blue.

You could even add the above line to the .gdbinit file in your home directory, so you always get a nice colourful prompt without having to think about it (see here for a brief guide to using .gdbinit files).

How does that work then?

It just uses the ANSI escape sequences (essentially a collection of non-printed text formatters) for colours – I might write up the escape sequences, and fun things you can do with them, in a future post, but for now the command above breaks down as follows:

\033 – this is the “escape” character
[ – escape is always followed by an open square bracket
0;34m – this is the colour. The zero is for bold (0 for off, 1 for on). The m indicates graphics mode.
(gdb) – this is your standard prompt
\033 – another escape sequence follows
[ – with the usual square bracket
0m – this reverts the graphics mode back to the default colour

For more colours, see the list here.

Eclipse CDT + GDB: Setting Watchpoints (Juno)

I was trying to watch a variable in Eclipse today and just could not find how to set it up. No matter what I did the Toggle Watchpoint option remained greyed out.

A watchpoint is more fun than a regular breakpoint, because the debugger will stop whenever the variable is changed, even if your program is busy doing something else (like overrunning the end of an array).

So after a bit of research it turns out that you can set watchpoints, but the variable type dictates how.

Global variables

If your variable is global, you need to double-click the variable to highlight it (anywhere in your source) and then select Run > Toggle Watchpoint. Until your variable is selected, this option will always be greyed out.

You can also right click on it in the Outline View and then select Toggle Watchpoint from the context menu.

In both cases a watchpoint properties box pops up so you can edit the details. Just click OK and the debugger will stop every time the variable is changed.

If the variable is not listed in the Outline View then sorry – it’s not global and you can’t use the Eclipse GUI to set it – but you can do this:

Local variables

When you’re debugging with gdb via Eclipse, there is a sneaky gdb console view that you can use to talk directly to the gdb session.

Select the console tab at the bottom and on the right-hand side click the Display Selected Console button. This will reveal a drop down menu. Choose [C/C++ Application] gdb.

And now, in the console itself, just type your watchpoint as if you were on the gdb command line (in the screenshot below I want to be notified if a local variable called count goes above the value of 45):

 

gdb console watchpoint

Ta da! Eclipse will now stop whenever your local variable changes.

GDB: Unable to find dynamic linker breakpoint function

Need more? See my GDB tutorial: Part 1Part 2Part 3.

You all know how much I loooooooove GDB, so what better thing to write about after a long time away?

If you’re seeing this message:

warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.

and all your stack frames look like this:

0x40000780 in ?? ()

gdb is trying to tell you that it cannot find the relevant ld library for the target it is debugging.

Huh?

Well, ld (linux-ld.so and ld.so) is responsible for locating and running all the shared libraries required by your executable. You must tell gdb where the target version of ld lives so that it can successfully track what your executable is up to.

You probably already know that when remote debugging you should have an unstripped copy of your target’s root filesystem available on your host. Then you can point gdb to the copy filesystem and it will be able to “see” the target’s files.

And that means a seamless debugging experience 🙂

Since ld is a system library, you needn’t add the path to this explicitly. Just point to the “root” of the copy filesystem and gdb is clever enough to find it.

To do this, use the sysroot command:

set sysroot /absolute/path/to/copy/of/target/root/filesystem

You can also use:

set solib-absolute-prefix /absolute/path/to/copy/of/target/root/filesystem

as this is simply an alias for the sysroot command.

Often you will see suggestions to use:

set solib-search-path /path/to/target/root/filesystem

However, this is checked after sysroot and is meant to be used for a list of colon separated paths to non-system libraries that you may be using on your target.

E.g. If you use a shared library from a third party for say, graphics, that isn’t part of the root filesystem, then you can set its path here.

One more tip:

If you are already connected to the target executable (with the target remote <ip:port> command), when you set your paths, you will get a useful confirmation of the libraries that are loaded on each command:

set sysroot /opt/target/root/
Reading symbols from /opt/target/root/lib/ld-linux.so.3...done. 
Loaded symbols for /opt/target/root/lib/ld-linux.so.3
set solib-search-path /home/faye/LIB/target/ 
Reading symbols from /home/faye/LIB/target/libTerrain.so...(no debugging symbols found)...done.
Loaded symbols for /home/faye/LIB/target/libTerrain.so 
Reading symbols from /home/faye/LIB/target/libAlien.so...done. 
Loaded symbols for /home/faye/LIB/target/libAlien.so

Once you know all your paths are set correctly, you can just add these commands to your GDB init file, to save you typing them in each time you run gdb.

Happy debugging 🙂

Need more? See my GDB tutorial: Part 1, Part 2, Part 3.