Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent the compiler from omitting types I don't explicitly instantiate?

Situation

This is a question about debugging. I have installed the GDB pretty printers for the standard library, but I find that they do not work correctly under many circumstances. For instance, debugging a piece of code with the following declaration:

std::map<int, int> foo;

I've compiled with -O0 -ggdb3, so I expected to have no trouble examining foo, and if I manually examine the structures, I experience no issues. However, the STL pretty printers do not work, because GCC seems to be omitting type information about nested types that my program does not explicitly instantiate.

For example, if I run the following command in GDB:

p foo.begin()

I see the following error message:

Python Exception <class 'gdb.error'> No type named
std::_Rb_tree_iterator<std::pair<int const, int> >::_Link_type.

This missing typename is an inner typedef, defined inside std::map::iterator. It's implementation dependent standard library support code, so it's not cross platform (or even guaranteed to continue existing between different versions of the implementation on the same platform).

However, if I declare something involving that type in the program, the pretty printer will work correctly.

std::_Rb_tree_iterator<std::pair<int const, int> >
   ::_Link_type *dummy = NULL;

Question

So, how do I instruct GCC not to remove the definitions for types in situations such as this, so they remain available to the debugger? Given that the STL implementation is not cross platform, a hacky workaround like declaring a bunch of dummy variables with a preprocessor macro does not seem like a scalable solution. Is there a flag I can pass to GCC to force recursive inclusion of template types? Or does GCC not support this at all? Has anyone else faced this problem and solved it?

Author's Note

GDB pretty printing is broken in GDB 7.7.1 (the most recent version in the ubuntu 14.04 repos as of the time of this writing) and cannot print pointers properly. Those looking at answering this question may find it useful to know that this is a known problem and that a bug has already been filed.

like image 930
Wug Avatar asked Apr 19 '15 21:04

Wug


1 Answers

So, how do I instruct GCC not to remove the definitions for types in situations such as this, so they remain available to the debugger?

I don't believe there is any way to instruct GCC to emit debug info for types that are not present in your program.

It is however a very strange program that instantiates std::map, but never uses any of its iterator-using methods.

if I declare something involving that type in the program

There should be no need to do that. Simply calling m.begin() or having a range for loop over the map somewhere in the program is enough to instantiate the iterator type.

like image 86
Employed Russian Avatar answered Nov 15 '22 07:11

Employed Russian