GNU LogoDebugging C++ templates is difficult. Debugging C++ templates with GDB can be an act of torture for even seasoned GDB users. I like GDB, but there are some tricks you should know when using it to debug templates. In this post, I deal with setting breakpoints.

Breakpoint Basics:

Setting a breakpoint in GDB is supposed to be simple. Here we set a breakpoint at line 50 in file main.cpp:

(gdb) b main.cpp:50
Breakpoint 1 at 0x804937a: file main.cpp, line 50.

We can also use the function name and GDB will attempt to find the correct location for us:

(gdb) b DoSomething
Breakpoint 2 at 0×8049334: file main.cpp, line 150

Simple, right? Just wait…

Breakpoint Gotchas:

GDB’s breakpoint logic is pretty handy for simple projects, but it can break down fast when things get more complicated.

For example, let’s say your application is plugin-driven, with each plugin being a separate library. Now assume each plugin has a Plugin.cpp file under it’s own Source directory. Try to set a breakpoint in the Initialize() method of the Plugin class:

(gdb) b Initialize
Breakpoint 3 at 0×8049717: file main.cpp, line 230

Oops! There is an Initialize() method in main.cpp and GDB thought that’s where we wanted to put it: wrong!

Okay, let’s be more specific:

(gbd) b Plugin::Initialize
Breakpoint 4 at 0×8046194: file Source/Plugin.cpp, line 89

Okay, that looks better, but which Plugin.cpp file did GDB put the breakpoint? How do we know it’s the file for the plugin we want?

If we used namespaces, then we can get more specific:

(gdb) b MY_PLUGIN_A::Plugin::Initialize
Breakpoint 5 at 0×8050039: file Source/Plugin.cpp, line 130

We can see from the address and line number that the previous breakpoint was at the wrong place. Okay, moving on…

Setting Breakpoint in Templates:

Templates can be much harder to set breakpoints in because we have to specify the exact prototype for the fully-defined template. We as programmers are used to the compiler handling the template type stuff for us, so it can be difficult to guess the correct type.

For example, assume we have some abstract class BarAbstract that uses the template Foo<> to make it concrete. Now assume we’re really clever and we want to hide this from the users of our class. We could use a typedef to hide the true type:

typedef Foo<BarAbstract> Bar;

Now, all the user needs to do is instantiate Bar without a thought to the Foo<> template.

int DoSomething()
{
Bar b;
return b.Baz();
}

So far so good? Okay, now how the heck do you set a breakpoint in the Baz() method of class Bar?

The quick answer: use objdump, c++filt, and grep to find the complete definition that GDB will need.

$ objdump -t libMyLib.so | c++filt | grep ‘BarAbstract.*Baz’
0000d2d6 w F .text 0000000a     MY_PLUGIN_A::Foo<MY_PLUGIN_A::BarAbstract>::Baz()

Now, simply copy-n-paste the full method definition to GDB when setting the breakpoint:

(gdb) b MY_PLUGIN_A::Foo<MY_PLUGIN_A::BarAbstract>::Baz()
Breakpoint 6 at 0×8048890: file Source/Bar.cpp, line 355

That’s it! Happy debugging!

Tagged with:  

6 Responses to Debugging: C++ Templates, Breakpoints, and GDB

  1. Scott Rippee says:

    Very nice!

    Reply

  2. umesh says:

    At least for compile errors, you can use Boost Concept Check Library which allows early detection of template use errors.
    You can look at this blog for information:
    http://cppguru.isa-geek.com/2009/01/c0x-concepts/ for more information.

    Reply

  3. Hi Tom,

    Nice post: this helps a lot! I am also glad to find another Christian geek.

    Cedric

    Reply

  4. Juan says:

    hi, Tom
    Nice! I learned a lot from your words. But now I have another one question on how to set a breakpoint at one line in template function. I only know how to stop at the beginning of template function but don’t know how to stop at one line in templates.

    Reply

  5. Anon says:

    Looks like you’ve a spelling mistake in your title

    s/brekpoints/breakpoints

    Cheers

    Reply

  6. andy says:

    great article. you saved my day! thanks.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>