Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing/Debugging libc++ STL with Xcode/LLDB

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:

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.

Has anyone been able to get any useful output from LLDB with libc++?

like image 290
cjserio Avatar asked Sep 24 '16 19:09

cjserio


People also ask

Does Xcode use LLDB?

Xcode uses the LLDB as the default debugging tool. The full form of LLDB is Low-level debugger. Breakpoints help a developer to stop the execution of the program at any point.

What does LLDB mean in Xcode?

What is LLDB? A low-level debugger (LLDB) is the default debugger used in Xcode and is part of the LLVM project. LLDB replaced GDB in XCode 5 and has several advantages, such as performance and scriptability.

What is LLDB Linux?

LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the larger LLVM Project, such as the Clang expression parser and LLVM disassembler.

Does LLDB work on Linux?

LLDB is improving on Linux. Linux is nearing feature completeness with Darwin to debug x86_64, i386, ARM, AArch64, IBM POWER (ppc64), IBM Z (s390x), and MIPS64 programs. For more details, see the Features by OS section below.


1 Answers

[] 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.

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) 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> >) $0 = 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:

(lldb) frame var my_vec[1] (Foo) my_vec[1] = (var1 = 10, var2 = 20) 

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:

(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 = 3 

Another way to work around this for debugging - if you are using C++11 - is by putting:

template class std::vector<MyClass> 

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.

like image 72
Jim Ingham Avatar answered Oct 01 '22 11:10

Jim Ingham