如何深入 shared_ptr [Netbeans、clang++、gdb]
How to drill down into shared_ptr [Netbeans, clang++, gdb]
我正在使用
- Netbeans C++ 8.0.2
- clang++ (Ubuntu clang 版本 3.6.0-2ubuntu1 (tags/RELEASE_360/final) (基于 LLVM 3.6.0))
- gdb (GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9)
在我的 "C++ Simple Tests," 中,每当我检查一个 shared_ptr 的变量时,我看到的所有值都是:
std::shared_ptr (count 1, weak 0) 0x64d3a0
或类似的。无法深入了解它实际指向的值。即使变量 window 中的树视图显示了其中一个扩展器图标,当我单击它时它也会消失。当我尝试取消引用它或在 "expressions" window 中调用它的 get()
函数时,我收到一条错误消息:
Could not find operator*.
和
Cannot evaluate function -- may be inlined
分别
如果我在实际程序中创建对值的引用,它不仅允许我向下钻取引用,而且 shared_ptr 也可以向下钻取(这对我来说似乎很可疑).我尝试了 -g3
和 -ggdb
,但没有任何区别。
是否有标准库的调试版本(libcxx 是默认的?),或者某个地方的设置可能会改善这种情况?或者也许是一种在变量 window 中列出私有 members/raw 视图的方法,这样我就可以自己解除对底层指针的引用?
在 Netbeans 中:
单击底部的 "Watches" 选项卡。现在点击顶部菜单中的 运行 > New Watch。
取消引用您拥有的地址,输入:*0x64d3a0
,然后单击“确定”。
gdb的一个缺陷是漂亮的打印代码只是为了打印,不能用来深入挖掘。此缺陷还会影响 "varobj" 功能,这是大多数 GUI 在与 gdb 就值显示进行通信时使用的功能。
有一些可能性可以使它变得更好。
首先,介绍一下背景。您不能调用 operator*
或 get
的原因是 gcc 通常不会发出始终内联的函数的外联副本。这是一项节省 space 的优化。 (您可以要求发生这种情况,但这种情况并不常见。)
因此,解决此问题的一种方法是使用新的 gdb xmethod
代码。您可以在 gdb 中编写一些 Python 代码来实现 get
之类的东西,这样即使编译器不合作,gdb 表达式也会按预期工作。这很方便! libstdc++ 附带其中一些,但我不知道具体是什么;你将不得不去挖掘。
我经常使用两种低技术含量的方法。
评论中提到——复制并粘贴指针值,转换为正确的类型。这工作可靠,但正如您所注意到的那样很痛苦。 Gdb 应该对这个习惯用法有一些 "varobj" 支持,这样 IDE 就可以做正确的事情而不会跳过箍。我相信有一个关于此的 gdb 错误。
绕过漂亮打印机直接深入对象表示。这有时会令人不快——特别是在 libstdc++ 中,有时对象表示确实不明显——但对于像智能指针这样的东西,它应该不会太糟糕。秘诀就是 print/r
,然后检查您看到的内容。 IDE 可以而且应该提供一种绕过漂亮打印的方法,"varobj" API 公开了此功能。不知道Netbeans有没有。
我正在使用
- Netbeans C++ 8.0.2
- clang++ (Ubuntu clang 版本 3.6.0-2ubuntu1 (tags/RELEASE_360/final) (基于 LLVM 3.6.0))
- gdb (GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9)
在我的 "C++ Simple Tests," 中,每当我检查一个 shared_ptr 的变量时,我看到的所有值都是:
std::shared_ptr (count 1, weak 0) 0x64d3a0
或类似的。无法深入了解它实际指向的值。即使变量 window 中的树视图显示了其中一个扩展器图标,当我单击它时它也会消失。当我尝试取消引用它或在 "expressions" window 中调用它的 get()
函数时,我收到一条错误消息:
Could not find operator*.
和
Cannot evaluate function -- may be inlined
分别
如果我在实际程序中创建对值的引用,它不仅允许我向下钻取引用,而且 shared_ptr 也可以向下钻取(这对我来说似乎很可疑).我尝试了 -g3
和 -ggdb
,但没有任何区别。
是否有标准库的调试版本(libcxx 是默认的?),或者某个地方的设置可能会改善这种情况?或者也许是一种在变量 window 中列出私有 members/raw 视图的方法,这样我就可以自己解除对底层指针的引用?
在 Netbeans 中:
单击底部的 "Watches" 选项卡。现在点击顶部菜单中的 运行 > New Watch。
取消引用您拥有的地址,输入:*0x64d3a0
,然后单击“确定”。
gdb的一个缺陷是漂亮的打印代码只是为了打印,不能用来深入挖掘。此缺陷还会影响 "varobj" 功能,这是大多数 GUI 在与 gdb 就值显示进行通信时使用的功能。
有一些可能性可以使它变得更好。
首先,介绍一下背景。您不能调用 operator*
或 get
的原因是 gcc 通常不会发出始终内联的函数的外联副本。这是一项节省 space 的优化。 (您可以要求发生这种情况,但这种情况并不常见。)
因此,解决此问题的一种方法是使用新的 gdb xmethod
代码。您可以在 gdb 中编写一些 Python 代码来实现 get
之类的东西,这样即使编译器不合作,gdb 表达式也会按预期工作。这很方便! libstdc++ 附带其中一些,但我不知道具体是什么;你将不得不去挖掘。
我经常使用两种低技术含量的方法。
评论中提到——复制并粘贴指针值,转换为正确的类型。这工作可靠,但正如您所注意到的那样很痛苦。 Gdb 应该对这个习惯用法有一些 "varobj" 支持,这样 IDE 就可以做正确的事情而不会跳过箍。我相信有一个关于此的 gdb 错误。
绕过漂亮打印机直接深入对象表示。这有时会令人不快——特别是在 libstdc++ 中,有时对象表示确实不明显——但对于像智能指针这样的东西,它应该不会太糟糕。秘诀就是
print/r
,然后检查您看到的内容。 IDE 可以而且应该提供一种绕过漂亮打印的方法,"varobj" API 公开了此功能。不知道Netbeans有没有。