最近我正在研究gdb7的python扩展,我只想用它编写一个小工具来在调试时显示友好的C++容器(例如list)的内容,但是在处理list时遇到了麻烦。这是我的C++代码供测试使用:

int main() {
list<int> int_lst;
for (int i = 0; i < 10; ++i)
    int_lst.push_back(i);

for(list<int>::const_iterator citer = int_lst.begin();
    citer != int_lst.end(); ++citer)
    cout << *citer << " ";
cout << endl;

return 0;
}

我在“用gdb调试”教程之后写了一个小的python代码,只是尝试显示int_lst的内容
import gdb
class Hello(gdb.Command):

    def __init__(self):
        super(Hello, self).__init__("plist", gdb.COMMAND_OBSCURE)

    def invoke(self, arg, from_tty):
        cpp_lst = gdb.parse_and_eval("int_lst")
        header = cpp_lst['_M_impl']['_M_node']
        next = header['_M_next']
        # next is _List_node_base, I have to cast it to its derived type for data
        next.dynamic_cast(gdb.lookup_type("std::_List_node<``int>").pointer())
Hello()

在C++ STL中,std::_ List_node_base是列表中节点的基类,但是只有派生的模板类std::_ List_node具有包含值的数据成员“_M_data”,因此我必须对其进行dynamic_cast,但gdb抱怨:
Error occurred in Python command: Couldn't determine value's most derived type for dynamic_cast

我已经花了几个小时,有经验的人可以为我提供有关此问题的一些提示,或者为我提供一些完成此小工具的建议吗?非常感谢您的帮助,谢谢!

最佳答案

没有更多信息,很难说出哪里出了问题。

GDB试图使用RTTI信息来查找该字段的完整对象。这有些失败。您可以尝试通过使用“将打印对象设置为开”从CLI再现问题,然后打印有问题的字段。

另外,您是否有特定的原因要使用dynamic_cast?只需使用普通的“cast”方法即可。我认为这将绕过这些检查。

请注意,对于这种特定情况,您可能应该只选择现有的libstdc++ pretty-print 。它们与gdb中现有的“print”命令集成在一起,并且已经可以处理libstdc++中的每个复杂数据结构。当您的程序使用libstdc++时,许多发行版会以自动启用该代码的方式发布所有这些代码。

关于c++ - 无法确定dynamic_cast值的最衍生类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16737496/

10-09 06:37
查看更多