【问题标题】:Calling method on a C++ object in LLDB, fails to give results在 LLDB 中调用 C++ 对象的方法,无法给出结果
【发布时间】:2017-09-04 06:18:23
【问题描述】:

我有一个 unordered_map 命名节点。声明如下:

unordered_map<T,shared_ptr<Vertex<T>>> nodes

Vertex 是一个声明如下的类:

template<typename T>
struct Vertex {

    Vertex(T pLabel) : label(pLabel) {};

    void addEdge(T destination,int weight) {
        edges[destination] = weight;
    }

    T label;
    unordered_map<T, int> edges;
};

我有一个接受顶点的 unordered_map 的方法,如下所示。

template<typename T>
void getMinSpanningTree(unordered_map<T,shared_ptr<Vertex<T>>>& nodes, T first, int infinityMarker) {

    cout << nodes.size() << endl;

    if(nodes.size() == 0) {
        return;
    }
    ...
    ...

当我在 LLDB 中停止执行并输入以下内容时:

(lldb) expr nodes.size()

我得到以下输出:

(lldb) expr nodes.size()
error: Couldn't lookup symbols:
  __ZNKSt3__113unordered_mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_10shared_ptrI6VertexIS6_EEENS_4hashIS6_EENS_8equal_toIS6_EENS4_INS_4pairIKS6_SA_EEEEE4sizeEv

所以,我不确定如何让调试器正确输出答案。以下行的标准输出,在输出控制台中打印 5:

cout << nodes.size() << endl;

这里是我使用函数和类的方式:

int main(int argc, const char * argv[]) {

    shared_ptr<Vertex<string>> v1 = make_shared<Vertex<string>>("V1");
    shared_ptr<Vertex<string>> v2 = make_shared<Vertex<string>>("V2");
    shared_ptr<Vertex<string>> v3 = make_shared<Vertex<string>>("V3");
    shared_ptr<Vertex<string>> v4 = make_shared<Vertex<string>>("V4");
    shared_ptr<Vertex<string>> v5 = make_shared<Vertex<string>>("V5");

    v1->addEdge("V2", 1);
    v1->addEdge("V3", 3);

    v2->addEdge("V1", 1);
    v2->addEdge("V3", 3);
    v2->addEdge("V4", 6);

    v3->addEdge("V1", 3);
    v3->addEdge("V2", 3);
    v3->addEdge("V4", 4);
    v3->addEdge("V5", 2);

    v5->addEdge("V2", 3);


    unordered_map<string,shared_ptr<Vertex<string>>> vertices;
    vertices[v1->label] = v1;
    vertices[v2->label] = v2;
    vertices[v3->label] = v3;
    vertices[v4->label] = v4;
    vertices[v5->label] = v5;

    getMinSpanningTree(vertices,v1->label,numeric_limits<int>::max());

    return 0;
}

打印节点,似乎转储了所有内容:

(std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > > >) $0 = size=5 {
  [0] = {
    __cc = {
      first = "V5"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208c68 strong=2 weak=1 {
        __ptr_ = 0x0000000100208c68
      }
    }
    __nc = {
      first = "V5"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208c68 strong=2 weak=1 {
        __ptr_ = 0x0000000100208c68
      }
    }
  }
  [1] = {
    __cc = {
      first = "V4"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208748 strong=2 weak=1 {
        __ptr_ = 0x0000000100208748
      }
    }
    __nc = {
      first = "V4"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208748 strong=2 weak=1 {
        __ptr_ = 0x0000000100208748
      }
    }
  }
  [2] = {
    __cc = {
      first = "V2"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208c08 strong=2 weak=1 {
        __ptr_ = 0x0000000100208c08
      }
    }
    __nc = {
      first = "V2"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208c08 strong=2 weak=1 {
        __ptr_ = 0x0000000100208c08
      }
    }
  }
  [3] = {
    __cc = {
      first = "V3"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x00000001002086e8 strong=2 weak=1 {
        __ptr_ = 0x00000001002086e8
      }
    }
    __nc = {
      first = "V3"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x00000001002086e8 strong=2 weak=1 {
        __ptr_ = 0x00000001002086e8
      }
    }
  }
  [4] = {
    __cc = {
      first = "V1"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208ba8 strong=2 weak=1 {
        __ptr_ = 0x0000000100208ba8
      }
    }
    __nc = {
      first = "V1"
      second = std::__1::shared_ptr<Vertex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::element_type @ 0x0000000100208ba8 strong=2 weak=1 {
        __ptr_ = 0x0000000100208ba8
      }
    }
  }
}

【问题讨论】:

  • gdb 是一个很棒的调试工具,你可以很容易地查找教程或阅读文档
  • 我的平台是 Mac OS X,我使用 Xcode。现在默认的调试器是 LLDB,它非常适合 swift 和 Objective-C。我也希望能够在其中有效地调试 C++。所以我有点不想切换到 GDB,除非那是我提高工作效率的唯一方法。
  • 我已经尝试过您在@jtbandes 发布的链接中的建议
  • 你能发布一个完整的例子吗?看起来上面的声明行被截断了,但您应该能够在一个可以逐字显示的简单源文件中实现这一点。了解您如何前向声明模板类解决​​方法也很有帮助。当我尝试它时,这对我有用,但我毫不怀疑 C++ 中的复杂性可能会破坏解决方法。也很高兴在那里看到一个例子。

标签: c++ lldb


【解决方案1】:

我很确定这与 jtbandes 上面给出的链接中描述的问题相同。如果我编译你的例子,那么做:

> nm a.out | grep size 
> 

没有匹配项,表明没有生成size 函数。请注意,如果代码不使用它们,编译器通常不会发出模板函数实例化,因此您实际上应该在某处调用“size”以增加它被发出的机会。但即使进行了这种更改,我仍然没有看到生成此方法。相反,使用始终是内联的。

调试器很少有机会正确调用函数的内联版本。因此,它在这里无法为您提供太多帮助。 clang 有一个错误,它与 STL 相关联,在 -O0 处内联时不那么激进。这是解决此问题的唯一实用解决方案。

链接问题中建议的解决方法是转发声明类。但是,我没有成功提出通过编译器的此类的前向声明。也许有更强的 C++-fu 的人可以?

printframe variable 可以看到地图的元素并打印其大小,但这是通过单独的机制完成的 - lldb“数据格式化程序”。如果您想了解更多有关其工作原理的信息,请参阅此处:

http://lldb.llvm.org/varformats.html

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 2015-10-25
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    相关资源
    最近更新 更多