LLDB(Swift):将原始地址转换为可用类型

时间:2015-04-04 00:22:46

标签: ios swift lldb

是否有可以将原始地址转换为可用的Swift类的LLDB命令?

例如:

(lldb) po 0x7df67c50 as MKPinAnnotationView

我知道这个地址指向MKPinAnnotationView,但它不在我可以选择的框架中。但是,我想将原始地址转换为MKPinAnnotationView,以便我可以检查其属性。这可能吗?

12 个答案:

答案 0 :(得分:98)

在Xcode 8.2.1和Swift 3下,lldb命令 po p 赢得了'使用类型变量。您需要使用swift命令 print 来检查键入的对象实例的属性。 (感谢cbowns's answer!)例如:

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
(lldb) expr -l Swift -- print($pin.alpha)

答案 1 :(得分:42)

您可以使用Swift的unsafeBitCast函数将地址强制转换为对象实例:

(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin

然后您可以像往常一样使用$pin - 访问属性,调用方法等。

查看此文章以获取更多信息:Swift Memory Dumping

答案 2 :(得分:23)

expression的lldb格式似乎在XCode 7.3中发生了变化。以下让我开始:

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self)

答案 3 :(得分:10)

从Xcode 8 / Swift 3开始,这里有什么对我有用。 (这是基于@sfaxon's answer。)

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)

答案 4 :(得分:9)

对于自定义类,您需要导入项目

expr -l Swift -- import MyTestProject
expr -l Swift --  let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)

答案 5 :(得分:8)

感谢上面的所有答案, unsafeBitCast 也适用于Xcode 8.3.2 / Swift 3 / macOS / Cocoa应用程序。

记住当前实例的地址

(lldb) p tabView.controlTint
(NSControlTint) $R10 = defaultControlTint

(lldb) p self
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 {
.....

稍后,检查一下

(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
(NSControlTint) $R20 = graphiteControlTint

(lldb) p $R11.tabView.controlTint
(NSControlTint) $R21 = graphiteControlTint

如果发生类似的事情

(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'

确保选择一个Swift源代码的堆栈帧而不是汇编器。

如果通过单击 暂停 按钮暂停应用程序或因异常而停止,则可能会发生这种情况。通过相应地选择堆栈帧,让 lldb 推断出正确的编程语言。

答案 6 :(得分:4)

Objective-C版

po ((MKPinAnnotationView *)0x7df67c50).alpha

答案 7 :(得分:4)

我花了更长的时间才知道我想承认。它类似于@afinlayson的答案,但是有更好的解释(我希望如此)和固定的语法

如果您想使用Xcode的视图层次结构调试器检查对象的属性,则可以使用: 默认情况下,您处于objc上下文中,因此必须将其切换到Swift上下文

  1. 首先导入您的项目(如果要使用在那里定义的某些类)

expr -l Swift -- import <YOUR PROJECT NAME>

  1. 使用对象的内存地址将其投射到所需的任何类

expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: <YOUR PROJECT NAME>.<YOUR CUSTOM CLASS NAME>.self)

  1. 从对象访问所需的任何值

expr -l Swift -- print($vc.<PROPERTY NAME>)

示例:

expr -l Swift -- import Football

expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)

expr -l Swift -- print($vc.velocity)

答案 8 :(得分:2)

最简单的方法,快速4

expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)

答案 9 :(得分:1)

po是一个别名,表示可以覆盖它。您可以使用objc处理十六进制地址来覆盖po

command regex po
s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/
s/(.+)/expression -O -- %1/

要查看其效果如何,可以告诉lldb扩展这些别名:

(lldb) settings set interpreter.expand-regex-aliases true

我还创建了https://github.com/kastiglione/swift_po,它是Swift的替代品po。它处理对象地址,并且还有其他一些改进。

答案 10 :(得分:0)

@Xi Chen的答案非常适合在Swift上下文中启动LLDB会话时使用。但是,在某些情况下,您可能已经在Swift上下文的 outside 断点处停止了;例如,当它是Objective-C API的符号断点时。

error: unknown type name 'let'
error: use of undeclared identifier 'unsafeBitCast'

在这种情况下,您将需要使用Objective-C进行旧的操作:

e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50

现在您可以像以前一样使用$pin

答案 11 :(得分:0)

当在 Swift lldb 上下文中并处理 NSObject 子类(例如 MKPinAnnotationView)时,可以说使用此 1-liner 故意切换回 obj-c lldb 上下文会更容易:

e -O -l objc -- 0x7df67c50

在 obj-c 上下文中,e -O -- 等价于 lldb 中的 po