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.

 

GDB Core Dump Files

What’s a Core Dump?

It’s a file created when your program terminates abnormally. It contains a snapshot of the program’s state at the time of the failure.

What does it look like?

On Linux it will appear in the same location as the executable and will be named something like:

core.4196

Where the number is the process id of the program while it was running.

And what can I do with it?

You can have a look at it using GDB! GDB can read a core file to give you valuable information about a crash after the event.

Some Linux distributions have the ability to create core files disabled by default – you need to type:

ulimit -c unlimited

before running the program to allow the creation of the core file when the program terminates.

To examine a core file, just pass it to gdb:

gdb core.324

GDB will load up all the info and it will look as though you have just run the program and seen the error. You’ll be able to view a backtrace and a range of other information, but it will be a frozen “snapshot” of execution.

Instant debugging!

GDB Init Files Save Time At Startup

I can’t leave the subject of GDB alone for too long, so today I thought I’d talk about GDB init files.

Each time GDB is run, it checks first your home directory and then the current directory for the existence of a file called .gdbinit. If it finds this file, it reads the contents and runs any commands it finds there.

Note: as of version 7.5 GDB needs permission to load files from anywhere other than your home directory. See this update for further details.

This is extremely handy if you are repeatedly debugging an executable and don’t want to keep typing in the same old commands at startup.

For example, if you always put a breakpoint in a certain method because you like it as a starting point, you can specify this in the .gdbinit file, exactly as you would on the command line for GDB:

b main

And if you just can’t be bothered to keep typing ‘r’ to run GDB once it’s loaded your program, you can specify that too:

b main
r

You can also add any arguments that you repeatedly type in:

set args param1 param2
b main
r

And any configuration settings that you might want:

set prompt debug-->
set args param1 param2
b main
r

Now all you have to do is run GDB on your exe as usual, but now it will set up a custom prompt, pass in your arguments, set a breakpoint in main, and even start the program for you.

Next thing you know, you’ve got a GDB prompt at the top of the main function and you’re ready to go!