How to debug C++11 code with unique_ptr in DDD (or gdb)?
Asked Answered
D

2

13

std::unique_ptr are nice, but I find them less comfortable when debugging in DDD or gdb.

I'm using the gdb pretty printers that are part of gcc (e.g., /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py). That is a big win for readability, for example:

$ print pTest
std::unique_ptr<MyType> containing 0x2cef0a0

However, dereferencing the pointer does not work:

$ print *pTest
Could not find operator*.

When I need to access the value, I have to manually copy the pointer and cast it to the correct type, for example:

print *((MyType*) 0x2cef0a0)

If the process is still running, this version works (still ugly but better):

print *pTest.get() // will not work if analyzing a core dump

The straightforward approach to Display *pTest in DDD does not work either. It only results in the following error:

<error: Could not find operator*.>

Is there a way to debug C++11 code with unique_ptr in DDD (without breaking the workflow like I do with my cumbersome workarounds)?


I'm not afraid to use gdb commands, but DDD integration would be a plus. For example, following pointers in data structures by just double-clicking on them is often faster than typing.

I already tried to drop the pretty printer, but it is also not optimal. The best that I could come up with is the following:

 print pTest._M_t->_M_head_impl
Dong answered 1/4, 2014 at 23:7 Comment(3)
May sound like a dumb question, but did you have to build the gcc compiler on your box from scratch? Or was it an RPM update? I had an issue with gdb recently when trying to debug some C++ 11 code, and found I'd not re-compiled gdb. I'm pretty sure that's not the case here, but I thought it may be worth asking.Hoeg
@Welshboy I'm currently using the official gcc 4.8.2 (20140206) and gdb 7.7 from Arch Linux.Rooke
You might try this: #322822 and in particular have a look at a gdbinit file. It looks like there are lots of custom things you can make gdb do. Good luck.Zoology
E
12

This problem is actually not related to C++11, unique_ptr or pretty printing. The problem is that gcc does not emit code for std::unique_ptr::operator* that could be called by gdb to dereference the unique_ptr. If you for instance add *pTest; to your code then gdb does perform the dereferencing.

A similar problem is described in the SO post How to `print`/evaluate c++ template functions in gdb. Almost the same problem is described for an auto_ptr at https://sourceware.org/ml/archer/2012-q1/msg00003.html. If I understand the thread correctly one workaround would be to patch the pretty printer and also print out the dereferenced pointer when printing the unique_ptr. A gdb bug report can be found at http://sourceware.org/bugzilla/show_bug.cgi?id=12937.

The gdb wiki at https://sourceware.org/gdb/wiki/STLSupport describes more pretty printing solutions, which could have other workarounds.

Edit: A more elegant solution forcing the compiler to emit code for all member templates including operator* is to explicitly instantiate the class:

template class std::unique_ptr<MyType>;
Exogenous answered 26/8, 2014 at 12:51 Comment(2)
where should I define this explicit instantiation?Shayne
From a technical point of view in exactly one of your translation units ("cpp file") after including the memory header and after the declaration of MyType (or the respective include) - see en.cppreference.com/w/cpp/language/…Exogenous
S
3

GDB has a feature called xmethods which allows you to reimplement C++ methods in Python. This makes get() and the operator* available in GDB even if the compiler did not explicitly emit code for them.

Make sure that you are loading not only the pretty printers but also the xmethods in your .gdbinit:

python
import sys
sys.path.insert(0, '/usr/share/gcc-8.2.1/python/')
# This would only enable the printers but not the xmethods:
# from libstdcxx.v6.printers import register_libstdcxx_printers
from libstdcxx.v6 import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
Sol answered 28/10, 2019 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.