C++ 如何调试C++;11在DDD(或gdb)中具有唯一ptr的代码?

C++ 如何调试C++;11在DDD(或gdb)中具有唯一ptr的代码?,c++,c++11,gdb,unique-ptr,ddd-debugger,C++,C++11,Gdb,Unique Ptr,Ddd Debugger,std::unique_ptr很好,但我发现在或中调试时,它们不太舒服 我使用的是属于gcc的gdb漂亮打印机(例如,/usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py)。这是可读性的一大胜利,例如: $ print pTest std::unique_ptr<MyType> containing 0x2cef0a0 print *((MyType*) 0x2cef0a0) 当我需要访问该值时,我必须手动复制指针并将其转换为正

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

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

$ print pTest
std::unique_ptr<MyType> containing 0x2cef0a0
print *((MyType*) 0x2cef0a0)
当我需要访问该值时,我必须手动复制指针并将其转换为正确的类型,例如:

$ print pTest
std::unique_ptr<MyType> containing 0x2cef0a0
print *((MyType*) 0x2cef0a0)
如果进程仍在运行,则此版本可以工作(仍然很难看,但更好):

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

<error: Could not find operator*.>

这个问题实际上与C++11、unique_ptr或pretty打印无关。问题是gcc没有为std::unique_ptr::operator*发出代码,gdb可以调用该代码来取消对unique_ptr的引用。例如,如果您添加
*pTest到您的代码,然后gdb执行解引用

SO post中描述了类似的问题。几乎同样的问题也出现在自动测试中。如果我正确理解了线程,一个解决方法是修补漂亮的打印机,并在打印唯一的\u ptr时打印出取消引用的指针。gdb错误报告可在上找到

位于的gdb wiki描述了更多漂亮的打印解决方案,这些解决方案可能还有其他解决方法

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

template class std::unique_ptr<MyType>;
模板类std::unique\u ptr;
 >  GDB有一个特性,它允许您在Python中重新实现C++方法。这使得
get()
操作符*
在GDB中可用,即使编译器没有显式地为它们发出代码

确保您不仅加载了漂亮的打印机,还加载了
.gdbinit
中的xmethods:

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

听起来可能是个愚蠢的问题,但您是否必须从头开始在您的机器上构建gcc编译器?还是RPM更新?最近我在调试一些C++ 11代码时遇到了GDB问题,发现我没有重新编译GDB。我很确定这里的情况并非如此,但我认为这可能值得一问。@Welshboy我目前正在使用Arch Linux的官方gcc 4.8.2(20140206)和gdb 7.7。您可以试试这个:尤其是看看gdbinit文件。看起来你可以让gdb做很多定制的事情。祝你好运。我应该在哪里定义此显式实例化?从技术角度来看,在包含
内存
头和声明
MyType
(或相应的包含)后,仅在一个翻译单元(“cpp文件”)中定义此显式实例化-请参阅
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