11

std::unique_ptr很好,但是在DDDgdb中调试时我发现它们不太舒服。

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

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

但是,取消引用指针不起作用:

$ print *pTest
Could not find operator*.

当我需要访问该值时,我必须手动复制指针并将其转换为正确的类型,例如:

print *((MyType*) 0x2cef0a0)

如果进程仍在运行,则此版本有效(仍然丑陋但更好):

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

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

<error: Could not find operator*.>

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


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

我已经尝试放弃漂亮的打印机,但它也不是最佳的。我能想到的最好的方法如下:

 print pTest._M_t->_M_head_impl
4

2 回答 2

12

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

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

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

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

template class std::unique_ptr<MyType>;
于 2014-08-26T12:51:41.900 回答
2

GDB 有一个称为xmethods的功能,它允许您在 Python 中重新实现 C++ 方法。即使编译器没有明确地为它们发出代码,这也使得GDBget()中可用。operator*

确保您不仅加载了漂亮的打印机,还加载了 xmethods .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
于 2019-10-28T14:17:33.577 回答