Without any reason, Xcode show an error when i whan ton print using the debuger console :
(lldb) po self
warning: Swift error in scratch context: error: failed to load module 'XXX'
.
Shared Swift state for XXX.app has developed fatal errors and is being discarded.
REPL definitions and persistent names/types will be lost.
error: expression failed to parse:
unknown error
It's an iOS project with cocoapods. I'm on an M1 pro chip.
Any idea ?
I would start with simply print(self) instruction and check what appears in the console.
I like also debug(self) function (prints the whole object hierarchy).
If you want to print thread, you can use Thread.callStackSymbols.forEach { print($0) }
Have you tried set a breakpoint and then browse the Variable List (left side of the Debug Area)?
Is there an LLDB command that can cast a raw address into a usable Swift class?
For example:
(lldb) po 0x7df67c50 as MKPinAnnotationView
I know that this address points to a MKPinAnnotationView, but it is not in a frame that I can select. But, I want to cast the raw address into a MKPinAnnotationView so that I can examine its properties. Is this possible?
Under Xcode 8.2.1 and Swift 3, the lldb command po or p won't work with the typed variable. You will need to use the swift command print to examine the properties of the typed object instance. (Thanks to cbowns's answer!) E.g.:
expr -l Swift -- import UIKit
expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
expr -l Swift -- print($pin.alpha)
You can use Swift's unsafeBitCast function to cast an address to an object instance:
(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin
Then you can work with $pin as usual – access properties, call methods, etc.
Check out this article for more information: Swift Memory Dumping.
The lldb format for expression seems to have changed in Xcode 7.3. The following got me started:
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self)
For Custom Classes you need to import your project
expr -l Swift -- import MyTestProject
expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)
Objective-C version
po ((MKPinAnnotationView *)0x7df67c50).alpha
As of Xcode 8/Swift 3, here's what worked for me. (This is based off #sfaxon's answer.)
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
Thanks to all the answers above, unsafeBitCast also works well with Xcode 8.3.2 / Swift 3 / macOS / Cocoa Application.
Memorize an address of current instance
(lldb) p tabView.controlTint
(NSControlTint) $R10 = defaultControlTint
(lldb) p self
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 {
.....
Later, examine them
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
(NSControlTint) $R20 = graphiteControlTint
(lldb) p $R11.tabView.controlTint
(NSControlTint) $R21 = graphiteControlTint
If something like this happens
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
error: use of undeclared identifier 'to'
(lldb) p $R11.tabView.controlTint
error: use of undeclared identifier '$R11'
make sure that choose one of the stack frames of Swift source code rather than assembler one.
It is likely to happen when the application was paused by clicking a Pause button or stopped with an exception. By choosing a stack frame accordingly, let lldb infer a proper programing language.
It took me longer to figure out that I'd like to admit. It's similar to #afinlayson answer, but with better explanation (I hope!) and fixed syntax
If you want to check properties of an objects using Xcode’s view hierarchy debugger then this will work:
You’re in objc context by default so you’ll have to switch it to Swift context
First import your project (if you want to use some of the classes defined there)
expr -l Swift -- import <YOUR PROJECT NAME>
Cast object using it’s memory address to whatever class you want
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: <YOUR PROJECT NAME>.<YOUR CUSTOM CLASS NAME>.self)
Access any value you want from the object
expr -l Swift -- print($vc.<PROPERTY NAME>)
Example:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
#Xi Chen's answer works perfectly when your LLDB session was started in a Swift context. However, in some cases you might have stopped in a breakpoint outside a Swift context; for example, when it's a symbolic breakpoint to Objective-C API, or when in Debug View Hierarchy mode (at least as of Xcode 11.4).
error: unknown type name 'let'
error: use of undeclared identifier 'unsafeBitCast'
In that case, you'll need to do it the old way using Objective-C:
e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50
and now you can use $pin as you would.
The easiest way, swift 4
expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
po is an alias, which means it can be overridden. You can override po by handling hex addresses using objc:
command regex po
s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/
s/(.+)/expression -O -- %1/
To see what effect this has, you can tell lldb to expand these aliases:
(lldb) settings set interpreter.expand-regex-aliases true
Also I have created https://github.com/kastiglione/swift_po, which is a substitute po for Swift. It handles object addresses, and has a few other improvements too.
When in Swift lldb context and dealing with NSObject subclass such as MKPinAnnotationView it's arguably easier to deliberately switch back to obj-c lldb context using this 1-liner:
e -O -l objc -- 0x7df67c50
where e -O -- is equivalent to po in lldb when in obj-c context.
When I run my Swift app in Xcode 7.3.1 (with standard Swift 2 compiler) and execution pauses at a breakpoint, I cannot inspect variables with po command. The first time I run po exists (exists is a non-optional Bool variable in current scope) I get a long error message (see below). From the second time I run the same command onwards, I receive error loading helper function: (null) message.
The app is compiled and run on the debug scheme, with no "deployment post processing" and None [-O0] optimization.
Variable contents appear correctly in the variable inspector panel of Xcode.
Same error appears with po self or any other variable both running on device and iOS simulator.
If I run a new clean project, debugging with po works correctly.
In current scope:
var exists: Bool = self.canRemoveAttachmentForEpisode(episode)
NSLog("Exists is now \(exists)") // Breakpoint is set here
This is what happens in the debugger panel:
po exists
error loading helper function: <EXPR>:141:9: warning: '--' is deprecated: it will be removed in Swift 3
--maxItemCounter
^~
-= 1
<EXPR>:237:14: warning: '++' is deprecated: it will be removed in Swift 3
i++
^~
+= 1
<EXPR>:267:19: warning: 'init(start:end:)' is deprecated: it will be removed in Swift 3. Use the '..<' operator.
let rng = Range(start: si, end: ei.advancedBy(-1))
^
<EXPR>:280:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
var $__lldb_error_result = __lldb_tmp_error
~~~~^~~~~~~~~~~~~~~~~~~~
_
<EXPR>:89:41: error: 'CustomStringConvertible' is ambiguous for type lookup in this context
if let csc = (x as? CustomStringConvertible) {
^~~~~~~~~~~~~~~~~~~~~~~
Swift.CustomStringConvertible:13:17: note: found this candidate
public protocol CustomStringConvertible {
^
Castamatic.CustomStringConvertible:1:17: note: found this candidate
public protocol CustomStringConvertible {
^
<EXPR>:101:41: error: 'CustomStringConvertible' is ambiguous for type lookup in this context
if let csc = (x as? CustomStringConvertible) {
^~~~~~~~~~~~~~~~~~~~~~~
Swift.CustomStringConvertible:13:17: note: found this candidate
public protocol CustomStringConvertible {
^
Castamatic.CustomStringConvertible:1:17: note: found this candidate
public protocol CustomStringConvertible {
^
(lldb)
(lldb) po exists
error loading helper function: (null)
(lldb)
I solved the issue. The problem was I was redefining an existing protocol:
protocol MyCustomStringConvertible {}
extension MyCustomStringConvertible where Self: RawRepresentable, Self.RawValue == String {
..
}
I redefined CustomStringConvertible protocol, or maybe Apple's CustomStringConvertible didn't exist when I wrote my own version of it. Probably the protocol is only used by po when debugging, so the error never came out at runtime.
My only doubt is this: shouldn't the compiler alert me for redefining an existing protocol?
Why po returns these strange errors? (with Xcode 6.4 & Swift)
I try to debug with p / po:
NSDictionary, String and NSNumber all getting similar kind of errors all the time.
For now, I use println() but I am curious what could be the reason?
error: A fatal parse error has occurred. LLDB may become unstable; please restart your debug session as soon as possible.
error: <EXPR>:1:11: error: use of undeclared type '$__lldb_context'
extension $__lldb_context {
^~~~~~~~~~~~~~~
<EXPR>:11:5: error: use of unresolved identifier '$__lldb_injected_self'
$__lldb_injected_self.$__lldb_wrapped_expr_7(
^
For swift language use println() method.For debugging in console you have to keep in mind that you can only get debug info for swift's variables, but can't get it for swift's constants. So change let someVariable to var someVariable.
then in debugger do po someVarible. It will work.
If it doesn't work for arrays & dictionary ,for arrays do something like po print(myArray). Same goes for dictionary.
I am unable to inspect variable state within dynamic frameworks in the lldb debugging console. I am able to inspect the same code when I add it to the main application. Why is this? Is there a workaround? Any ideas?
(lldb) po URLSessionDataTask
error: <EXPR>:1:1: error: use of unresolved identifier 'URLSessionDataTask'
URLSessionDataTask
^
I had the same situation. I could create a class instant of anything in the main app but nothing in the dynamic libraries, when it was Swift code.
(lldb) exp let $a = RustyAppInfo() //class from framework
error: <EXPR>:3:10: error: use of unresolved identifier 'RustyAppInfo'
Fix for me:
(lldb) expr -- import rusty_nails //framework name
(lldb) exp let $a = RustyAppInfo()
My lldb version: 902.0.79.7. Notice, lldb knew I was trying to write swift code. In an iOS app, where you have Swift and Objective-C code, I always find it useful to type:
(lldb) settings set target.language swift
Answer was inspired by LLDB (Swift): Casting Raw Address into Usable Type