std::unique_ptr
很好,但是在DDD或gdb中调试时,我发现它们不太舒服。
我正在使用gdb漂亮的打印机,它们是gcc的一部分(例如,/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
这个问题实际上与C++11,unique_ptr或漂亮的打印无关。问题是 gcc 不会发出 std::unique_ptr::operator* 的代码,gdb 可以调用这些代码来取消引用unique_ptr。例如,如果您将*pTest;
添加到代码中,则 gdb 会执行取消引用。
类似的问题在SO帖子中描述了如何在gdb中"打印"/评估c ++模板函数。对于 https://sourceware.org/ml/archer/2012-q1/msg00003.html 的auto_ptr,几乎描述了相同的问题。如果我正确理解线程,一种解决方法是修补漂亮的打印机,并在打印unique_ptr时打印出取消引用的指针。gdb 错误报告可以在 http://sourceware.org/bugzilla/show_bug.cgi?id=12937 找到。
https://sourceware.org/gdb/wiki/STLSupport 的 gdb wiki 描述了更漂亮的打印解决方案,其中可能有其他解决方法。
编辑:强制编译器发出所有成员模板(包括运算符*)的代码的更优雅的解决方案是显式实例化类:
template class std::unique_ptr<MyType>;
GDB有一个名为xmethods的功能,它允许你在Python中重新实现C++方法。这使得 get()
和 operator*
在 GDB 中可用,即使编译器没有为它们显式发出代码。
确保您不仅加载了漂亮的打印机,还加载了.gdbinit
中的 x方法:
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