Xcode lldb error: can't print out Swift variable - get $__lldb_injected_self.$__lldb_wrapped_expr_x instead
As a workaround you can print it in the lldb
debugger using:
frame variable variablename
Also possible using shortened syntax for quicker typing
fr v variablename
Since XCode 10.2 an ever simpler lldb
syntax is supported:
v variable
Update - new workarounds:
Print stack addresses:
v -L variablename
po
like on stack frame variable.property
v -o variablename.property
Swift like p
e unsafeBitCast(address, to: ClassName.self)
Update2 - new workaround applicable for Swift classes being wrappers of objc classes.
Example:
v response
(HTTPURLResponse) response = 0x0000000283ba7640 {
if v
works^:
e -l objc -- (int)[0x0000000283ba7640 statusCode]
(int) $2 = 404
I'd appreciate reports what is actually helpful and works. Thanks.
More information on this kind of capabilities can be found here:
https://developer.apple.com/library/content/documentation/General/Conceptual/lldb-guide/chapters/C5-Examining-The-Call-Stack.html
LLDB fails to examine variables (in Xcode)
Sorry in advance for the essay, but hopefully the info will be worth the read...
lldb has two ways of looking at variables(*): print
and frame variable
.
print
isn't really meant primarily for printing variables - that's just a side effect of what it really does. print
is an alias for expression
which gives you a little more sense of what it is: a full expression evaluator which runs the expression you pass at the point where you are stopped in your code.
It builds a context that emulates the code at the current pc (including the Class/Protocol context) and then takes the snippet you pass it, compiles it in that context, JIT's the result, inserts the JIT'ed code into the process you are debugging and runs it. That's quite powerful - you can change values, call functions in your program, introduce new functions, new types, etc. But there is also a lot of machinery just to get it going, and with swift some of this machinery is tricky to get right.
frame variable
can only print locals and arguments in the current frame (with the -g
flag it can also print globals & statics). It can't call functions, or any of the other fancy things print
can do. It does understand a limited subset of the variable access syntax, so:
(lldb) frame variable foo.bar.baz
will work. But under the covers, all it needs to do is read the debug information to find the variable, its type, and where it is in memory, and then it can extract the value from that information. So it is faster and more robust for what it does do - which is a large percentage of the work people generally ask print
to do.
Note, you can get "object printing" for variables you access with frame variable
by using the -O
flag, and it supports the same formatting options for results as print
. For context, the Xcode "Locals" view is roughly equivalent to calling frame variable
.
I tend to use frame variable
for simple locals printing, but even if you like to use one command for all your needs - which will be print
- it's good to know that there's a fallback if print
is failing for some reason.
Back to your examples...
Example 1: one of the things print
does in Swift is introduce all the visible local variables into the context of the expression, so they are available to your code. The error in Example 1 is because one of the local variables couldn't be realized - maybe it was a only specified by a protocol conformance and we couldn't figure out what it really was - so we failed building the context, which means the parse or JIT steps failed. The print
code does a pre-scan for this sort of failure and omits failing locals, but you've found a case this scan misses.
frame variable
would have probably also failed to print runOnce
but since it doesn't depend on the current context, the inability to do that wouldn't have affected your ability to print other variables.
If you can reproduce this issue, even if you can't make the project available to us we can often figure out what's going on from lldb's debugging log. So drive the debug session to the point where the print is going to fail, and do:
(lldb) log enable -f /tmp/lldb-log.txt lldb expr types
then run the failing expression. Then grab that log, and file a bug as described here:
https://swift.org/contributing/#reporting-bugs
Example 2: Was activeNetworkRequests a property? Those require us to call the "get" method to access them, and I have seen a few cases where lldb doesn't emit the code to call the property getters correctly. The log above will show us the code that was emitted, and we might be able to tell from there what went wrong. Of course, if you can make a test case you can send with the bug that is always best, but that's often not possible...
(*)For gdb users this is pretty close to the info locals
vrs. print
...
Related Topics
Arkit: Placing an Scntext at a Particular Point in Front of the Camera
Simpliest Solution to Check If File Exists on a Webserver. (Swift)
Swift. Could Not Build Objective-C Module 'Alamofire'
Isn't There an How to Pinch to Zoom in an Image in Swiftui
Swift: Testing Against Optional Value in Switch Case
Is There a Difference Between Swift 2.0 Protocol Extensions and Java/C# Abstract Classes
Color Attribute Is Ignored in Nsattributedstring with Nslinkattributename
Implicitly Unwrapped Optional Made Immutable
How to Print Out the Method Name and Line Number in Swift
Querying Below Autoid's in Firebase
Closure Use of Non-Escaping Parameter May Allow It to Escape
Swift Make Method Parameter Mutable
Swift Custom Context Menu Previewprovider Can Not Click Any View Inside(Using Tapgesture)