使用 Xcode/LLDB 打印/调试 libc++ STL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39680320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing/Debugging libc++ STL with Xcode/LLDB
提问by cjserio
I'm trying to use LLDB within Xcode 8 to debug very basic STL. I used to be able to print a vector like this:
我正在尝试在 Xcode 8 中使用 LLDB 来调试非常基本的 STL。我曾经能够打印这样的矢量:
p myvector[0]
to see whatever was in the first vector index. Now when I do that, I get this error:
查看第一个向量索引中的内容。现在,当我这样做时,我收到此错误:
error: Couldn't lookup symbols:
__ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm
Instead, I have to type this:
相反,我必须输入:
p myvector.__begin_[0]
in order to get any output.
以获得任何输出。
I tried importing the libcxx.py and unordered_multi.py scripts from the LLDB svn repository but that doesn't seem to change anything.
我尝试从 LLDB svn 存储库导入 libcxx.py 和 unordered_multi.py 脚本,但这似乎没有任何改变。
Has anyone been able to get any useful output from LLDB with libc++?
有没有人能够使用 libc++ 从 LLDB 获得任何有用的输出?
回答by Jim Ingham
[]
is an operator method on std::vector
, so to print the expression you want, lldb would have to be able to call the []
method. The problem here is that the STL on OS X is aggressive about inlining everything it can, and not wasting space producing out of line copies of the same functions. That's great for optimized code, but not so good for debugging because it leaves the debugger with no []
operator to call. That's the error message you are seeing.
[]
是 上的运算符方法std::vector
,因此要打印您想要的表达式,lldb 必须能够调用该[]
方法。这里的问题是 OS X 上的 STL 积极地内联它所能做的一切,而不是浪费空间生产相同功能的外联副本。这对于优化代码来说非常有用,但对于调试来说并不是那么好,因为它使调试器没有[]
可调用的运算符。这就是您看到的错误消息。
If you just want to see the elements in this vector, you can use the lldb "STL data formatters"to do this work for you. They know how most STL types are laid out, and can print the elements of most container types. For instance:
如果您只想查看此向量中的元素,可以使用 lldb “STL 数据格式化程序”为您完成这项工作。他们知道大多数 STL 类型的布局方式,并且可以打印大多数容器类型的元素。例如:
(lldb) expr my_vec[0]
error: Couldn't lookup symbols:
__ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEixEm
but:
但:
(lldb) expr my_vec
(std::__1::vector<Foo, std::__1::allocator<Foo> >) (lldb) frame var my_vec[1]
(Foo) my_vec[1] = (var1 = 10, var2 = 20)
= size=2 {
[0] = (var1 = 10, var2 = 20)
[1] = (var1 = 10, var2 = 20)
}
There is also another command "frame variable"which can inspect static objects, and hooks into the data formatters. It can't call functions and do other more complex expression parser tasks, but it does know how to use the STL data formatters to retrieve individual elements:
还有另一个命令“帧变量”可以检查静态对象,并连接到数据格式化程序中。它不能调用函数和执行其他更复杂的表达式解析器任务,但它知道如何使用 STL 数据格式化程序来检索单个元素:
(lldb) frame var -L my_vec[1]
0x0000000100100348: (Foo) my_vec[1] = {
0x0000000100100348: var1 = 10
0x000000010010034c: var2 = 20
}
(lldb) expr printf("%d\n", ((class Foo *) 0x0000000100100348)->var1)
10
(int) = 3
You can even use frame var's -L
option to locate the elements of the vector, and then you can cast the address to pass it to other functions:
您甚至可以使用 frame var 的-L
选项来定位向量的元素,然后您可以将地址转换为将其传递给其他函数:
template class std::vector<MyClass>
Another way to work around this for debugging - if you are using C++11 - is by putting:
解决此问题以进行调试的另一种方法 - 如果您使用的是 C++11 - 是通过放置:
#include <vector>
template<typename T>
struct Vector : std::vector<T>
{
Vector(size_t n)
: std::vector<T>{n}
{}
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
};
struct XXX
{
int x;
};
void func()
{
std::vector<XXX> a{10};
Vector<XXX> b{10};
auto x = b[0]; // gcc will produce an assembler code of operator[] for debug purpose
1; // as a break point
}
in your code somewhere. That will instruct the compiler to emit out-of-line copies of all the template functions for this specialization. That isn't a great general solution, and you only want to do it for debug builds, but it does let you call these functions and use them in complex expressions.
在您的代码中的某个地方。这将指示编译器为此特化发出所有模板函数的外联副本。这不是一个很好的通用解决方案,您只想为调试版本执行此操作,但它确实允许您调用这些函数并在复杂表达式中使用它们。
回答by Tora
The similar problem also happens with me: error: Couldn't lookup symbols:
类似的问题也发生在我身上: error: Couldn't lookup symbols:
My solution is to explicitly use the questioned function somewhere in a source code.
我的解决方案是在源代码中的某处明确使用有问题的函数。
(lldb) p a[0]
error: Couldn't lookup symbols:
__ZNSt3__16vectorI3XXXNS_9allocatorIS1_EEEixEm
(lldb) p b[0]
(XXX) (lldb) image lookup -r -n 'XXX.*operator'
1 match found in /Users/xxx/Library/Developer/Xcode/DerivedData/xxx:
Address: sandbox[0x00000001000011f0] (sandbox.__TEXT.__text + 256)
Summary: sandbox`Vector<XXX>::operator[](unsigned long) at main.cpp:19
= (x = 0)
Set a breakpoint on the line of 1; and run it.
在1的行上设置断点;并运行它。
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::reference
vector<_Tp, _Allocator>::operator[](size_type __n)
{
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
Bingo!! Does the function exist in a TEXT block?
答对了!!该函数是否存在于文本块中?
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
I am not sure, but I had learned this before. In a debugging stage, instead of production stage. If we set a breakpoint on a line in a function of a template, what would a debugger do? Setting breakpoints, actually replacing some existing assembler code with trap or jump, here and there everywhere the template is applied? Or just setting a single breakpoint in a function? It is written as a template. So it should be inlined in a production stage. In a debugging stage, however, the function is not inlined and written as a normal function. Please do not simply believe what I say here. Please confirm by yourself. Consult documentation of gcc,
clang,
and lldb.
我不确定,但我以前学过这个。在调试阶段,而不是生产阶段。如果我们在模板函数的一行上设置断点,调试器会做什么?设置断点,实际上是用陷阱或跳转替换一些现有的汇编代码,到处都是应用模板的地方?或者只是在函数中设置一个断点?它是作为模板编写的。所以它应该在生产阶段内联。然而,在调试阶段,该函数并未内联并作为普通函数编写。请不要简单地相信我在这里所说的话。请自行确认。查阅文档gcc,
clang,
和lldb.
#include <vector>
of MacOS 10.13.6, Xcode Version 9.4.1 has a macro _LIBCPP_INLINE_VISIBILITY
:
#include <vector>
MacOS 10.13.6 的 Xcode 版本 9.4.1 有一个宏_LIBCPP_INLINE_VISIBILITY
:
inline _LIBCPP_INLINE_VISIBILITY
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
The _LIBCPP_INLINE_VISIBILITY
is defined in #include <__config>
as:
该_LIBCPP_INLINE_VISIBILITY
定义在#include <__config>
为:
(lldb) p b[0]
error: Couldn't lookup symbols:
__ZN6VectorI3XXXEixEm
Such keywords hidden
and __always_inline__
seem to control behavior.
这样的关键词hidden
,并__always_inline__
似乎控制行为。
When I added inline _LIBCPP_INLINE_VISIBILITY
to the sample solution code above:
当我添加inline _LIBCPP_INLINE_VISIBILITY
到上面的示例解决方案代码时:
resulted in:
导致:
##代码##I hope that help and somebody look into much more deeply.
我希望帮助和有人更深入地研究。