【问题标题】:shared-ptr map with lldb pretty printers带有 lldb 漂亮打印机的共享 ptr 映射
【发布时间】:2017-11-16 22:45:51
【问题描述】:

我有一个 std::map,我使用 shared_ptrs 作为键:

std::map<shared_ptr<object>, shared_ptr<object>>

但是,在调试时,我无法在 macOS 上使用 lldb 或在 linux 上使用 gdb 打开这些地图。使用 gdb,通过修改文件 libstdcxx/v6/printers.py 并将迭代器添加到 SharedPointerPrinter 类(代码如下所示),此问题已在 Ubuntu 上得到修复。但是,我不知道如何为 lldb 解决此问题。如果有人可以帮助我或为我指明正确的方向,那就太好了。

如果您需要其他信息来帮助我解决此问题,请告诉我,我很乐意提供。

class SharedPointerPrinter:
    "Print a shared_ptr or weak_ptr"

    class _iterator:
        def __init__(self, sharedPointer):
            self.sharedPointer = sharedPointer
            self.managedValue = sharedPointer.val['_M_ptr']
            self.count = 0

        def __iter__(self):
            return self

        def next(self):
            if self.managedValue == 0:
                raise StopIteration
            self.count = self.count + 1
            if (self.count == 1):
                return ('Use count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_use_count'])
            elif (self.count == 2):
                return ('Weak count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_weak_count'] - 1)
            elif (self.count == 3):
                return ('Managed value', self.managedValue)
            else:
                raise StopIteration

    def __init__ (self, typename, val):
        self.typename = typename
        self.val = val

    def children (self):
        return self._iterator(self)

    def to_string (self):
        state = 'empty'
        refcounts = self.val['_M_refcount']['_M_pi']
        if refcounts != 0:
            usecount = refcounts['_M_use_count']
            weakcount = refcounts['_M_weak_count']
            if usecount == 0:
                state = 'expired, weakcount %d' % weakcount
            else:
                state = 'usecount %d, weakcount %d' % (usecount, weakcount - 1)
        return '%s (%s) to %s' % (self.typename, state, self.val['_M_ptr'])

【问题讨论】:

    标签: c++ shared-ptr lldb stdmap


    【解决方案1】:

    您可以使用本页所述的 lldb 的 Python 数据格式化程序执行几乎相同的操作:

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

    lldb 具有用于 clang 版本的 STL 的 std::map 和 std::shared_ptr 的数据格式化程序。例如,我看到:

    (lldb) fr v a_map
    (std::__1::map<std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::less<std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::allocator<std::__1::pair<const std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > >) a_map = size=1 {
      [0] = {
        first = "some text" strong=2 weak=1 {
          __ptr_ = "some text"
        }
        second = "other text" strong=2 weak=1 {
          __ptr_ = "other text"
        }
      }
    }
    

    伙计,那些 C++ 类型很冗长!

    还有一些用于 gcc 的 STL 的格式化程序,但我不太了解这些格式化程序的状态。

    IIUC 数据格式化程序可用于 gdb 中的表达式。在 lldb 中,frame variable 命令将接受简单的结构访问表达式,因此您可以这样做:

    (lldb) frame var a_map[0].first
    (const std::__1::shared_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >) a_map[0].first = "some text" strong=2 weak=1 {
      __ptr_ = "some text"
    }
    

    但是你不能在完整的表达式解析器中使用数据格式化程序产生的子项。

    【讨论】:

      猜你喜欢
      • 2013-06-20
      • 1970-01-01
      • 2011-07-02
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多