如何在 DDD(或 gdb)中使用 unique_ptr 调试 C++11 代码?

2022-01-20 00:00:00 gdb c++ c++11 unique-ptr ddd-debugger

std::unique_ptr 很好,但我发现在 DDD 或 gdb.

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

我正在使用作为 gcc 一部分的 gdb 漂亮打印机(例如,/usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py).这是可读性的一大胜利,例如:

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

在 DDD 中 Display *pTest 的直接方法也不起作用.它只会导致以下错误:

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

<error: Could not find operator*.>

有没有办法在 DDD 中使用 unique_ptr 调试 C++11 代码(不会像我使用繁琐的解决方法那样破坏工作流程)?

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)?

我不怕使用 gdb 命令,但 DDD 集成将是一个加分项.例如,双击数据结构中的指针通常比键入要快.

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

推荐答案

这个问题其实和C++11、unique_ptr或者漂亮的打印无关.问题是 gcc 不会为 std::unique_ptr::operator* 发出代码,gdb 可以调用这些代码来取消对 unique_ptr 的引用.例如,如果您将 *pTest; 添加到您的代码中,则 gdb 会执行取消引用.

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.

SO 帖子中描述了类似的问题 How to`print`/评估 gdb 中的 c++ 模板函数.https://sourceware.org/ml 中的 auto_ptr 描述了几乎相同的问题/archer/2012-q1/msg00003.html.如果我正确理解线程,一种解决方法是修补漂亮的打印机,并在打印 unique_ptr 时打印出取消引用的指针.可以在 http://sourceware.org/bugzilla/show_bug.cgi 找到 gdb 错误报告?id=12937.

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.

https://sourceware.org/gdb/wiki/STLSupport 上的 gdb wiki 描述更漂亮的打印解决方案,可能还有其他解决方法.

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

强制编译器为包括 operator* 在内的所有成员模板发出代码的更优雅的解决方案是显式实例化类:

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>;

相关文章