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


92

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

例如:

(lldb) po 0x7df67c50 as MKPinAnnotationView

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

Answers:


151

在Xcode 8.2.1和Swift 3下,lldb命令pop不适用于类型变量。您将需要使用swift命令print检查键入的对象实例的属性。(感谢大人们的回答!)例如:

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

37
这真的不应该那么难
Departamento B

这有点反常。我以为我不需要(lldb)在控制台中输入。但是没有它就行不通。
蜂蜜

2
在Objective-C中有办法做到这一点吗?
p0lAris

我一直在回头。我可能应该为expr -l Swift -- ..
Koen

49

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

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

然后,您可以$pin照常使用–访问属性,调用方法等。

请查看本文以获取更多信息:Swift Memory Dumping


对于第一个陈述,我认为您忘记了“ expr”或“ expression”。否则效果很好!
jarrodparkes

2
我在Xcode 7.2中遇到“错误:使用未声明的标识符'unsafeBitCast'”。
devios1

8
除了该错误(@devios),它还在7.3.1中显示另一个错误:“错误:未知类型名称'let'”
carlos_ms

3
请注意,根据上下文,您可能需要先使用以下命令将lldb切换为Swift模式 (lldb) settings set target.language swift。另外,在某些情况下(例如,在从应用程序转换为类型时打破了应用程序模块的范围),您可能需要在e import MyApp
前后添加

25

的lldb格式expression似乎已在Xcode 7.3中更改。以下让我开始:

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

14

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

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

1
我收到错误消息:没有这样的模块“ MyProjectName”。有什么想法如何解决?
亚历山大·斯蒂芬尼辛

@AlexanderStepanishin尝试设置线程/堆栈路径,例如:“ MyApp>线程1> 12主线程”
Juanmi

12

从Xcode 8 / Swift 3开始,这对我有用。(这是基于@sfaxon的回答。)

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

10

感谢以上所有答案,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推断适当的编程语言。


10

Objective-C版本

po ((MKPinAnnotationView *)0x7df67c50).alpha

1
这对我来说非常合适。就我而言,我在Debug View Hierarchy视图中,右键单击视图,然后选择Print description of...。那给了我一个内存地址和类型,我可以放入上面的代码中。很高兴知道可视化调试器将控制台放入了Obj-C框架。
Trev14

6

我花了更长的时间才知道我想承认。它类似于@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)


5

当您的LLDB会话在Swift上下文中启动时,@ Xi Chen的答案非常有效。但是,在某些情况下,您可能已在Swift上下文之外的断点停止;例如,当它是Objective-C API的符号断点时,或处于Debug View Hierarchy模式(至少从Xcode 11.4开始)时。

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

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

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

现在您可以按需使用了$pin


3

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

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,它可以替代poSwift。它处理对象地址,并且还有其他一些改进。


从您的链接开始,expression -l objc -O -- 0x76543210这只是对我的响应,不需要知道地址中的变量类!
tontonCD

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.