在lldb中设置大型数据结构的观察点

时间:2018-08-29 07:46:44

标签: c++ vector lldb watchpoint

我正在学习lldb,我很好奇您如何为较大的数据结构(例如矢量)设置观察点。我知道我可以使用打印并且可以使用,但是我收到一条消息,说不支持大小为“ x”的监视点。有没有解决的办法?感谢您的帮助!

(lldb) s
Process 36110 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x0000000100001600 a.out`main at test.cpp:10
   7        vector<int> arr;
   8        arr.push_back(1);
   9        arr.push_back(2);
-> 10       arr.push_back(3);
   11       arr.push_back(4);
   12       arr.push_back(5);
   13
Target 0: (a.out) stopped.
(lldb) print arr
(std::__1::vector<int, std::__1::allocator<int> >) $2 = size=2 {
  [0] = 1
  [1] = 2
}
(lldb) w s v arr
error: Watchpoint creation failed (addr=0x7ffeefbff458, size=24, variable expression='arr').
error: watch size of 24 is not supported

1 个答案:

答案 0 :(得分:2)

如果您使用的是Mac,则x86_64体系结构允许4个单独的监视区域,每个区域最多8个字节。目前,每个监视请求lldb将仅使用一个区域。它可以将多个监视区域组合在一起,以处理适用于此结构的较大请求。随时通过http://bugs.llvm.org提交对此功能的增强请求。但是观察点实际上是有限的资源,因此您通常必须对要观察的内容非常有针对性-这可能就是为什么没人能支持大于8个字节的原因。

如果要在元素添加到向量中或从向量中删除元素时停止,则足以观察向量中的结束指针(即__end_)。您可以通过--raw参数将“ frame var”看到向量的实际内胆:

(lldb) fr v --raw arr
(std::__1::vector<int, std::__1::allocator<int> >) arr = {
  std::__1::__vector_base<int, std::__1::allocator<int> > = {
    __begin_ = 0x0000000100400000
    __end_ = 0x000000010040001c
    __end_cap_ = {
      std::__1::__compressed_pair_elem<int *, 0, false> = {
        __value_ = 0x0000000100400038
      }
    }
  }
}

只要向量增大或缩小,结束标记都会被调整,因此设置了一个观察点:

(lldb) watch set v arr.__end_
Watchpoint created: Watchpoint 1: addr = 0x7ffeefbff1c8 size = 8 state = enabled type = w
    declare @ '/tmp/vectors.cpp:6'
    watchpoint spec = 'arr.__end_'
    new value: 0x000000010030020c

将捕获push_back,擦除等

如果要在向量值更改时停止,则必须注意各个值;只需播放32个字节,您就不会观看有意义大小的向量中的所有数据。当然,当向量调整大小时,您对旧数据的观察点现在将指向已释放的内存...