快速在 LLDB 中使用 po
Posted
技术标签:
【中文标题】快速在 LLDB 中使用 po【英文标题】:po in LLDB with swift 【发布时间】:2014-09-07 06:20:00 【问题描述】:如何使用 LLDB 在 Swift 应用程序中绘制变量的值?
之前是po variable_name
现在我通常会遇到一些令人讨厌的错误,例如:
(lldb) po a
error: <EXPR>:11:5: error: use of unresolved identifier '$__lldb_injected_self'
$__lldb_injected_self.$__lldb_wrapped_expr_2(
^
【问题讨论】:
是的,Swift 中的调试目前依赖于println
。
我遇到了类似的调试器错误,仅在尝试检查 let
常量时发生;看看我的问题here——它原来是 Xcode 6 中的一个错误。
编译器团队的人员似乎正在征集出现这些问题的代码示例/项目:devforums.apple.com/message/1106278#1106278。对此事业的任何贡献肯定会受到所有人的赞赏(并且肯定会是一个快乐的好伙伴)
我已经使用当前的 Xcode 和 Swift 测试打印对象进行了一些测试。也许这会有所帮助。
【参考方案1】:
这个错误听起来可能是因为 DWARF 没有告诉 LLDB 在哪里可以找到您的 self
对象。鉴于 Swift 的性质,LLDB 需要知道 self 的类型,以便能够在本地范围内注入表达式。
找出这是否是您的问题的一种方法是在 LLDB 提示符处执行:
(lldb) frame variable -L self
您可能不会看到它的位置。值得填写一个错误报告,只是为了跟踪您的特定 repro 案例。
无论如何,要解决您的大部分问题。在 Swift 中,没有像 ObjC 那样的语言认可的“打印描述”机制,所以虽然你可以输入 po self
,除非 self 是 Objective-C 类型,你会看到几乎与“p self”相同的东西甚至“帧变量自我”会告诉你——这完全基于 LLDB 数据格式化机制。如果您想使用它来自定义 Swift 对象的外观,则必须参考:http://lldb.llvm.org/varformats.html
【讨论】:
Xcode 6 最终版发布了,他们无法实现在调试期间观察任何变量值的基本功能。 @enrico:获取 Swift 符号的最新技术是什么? po 是否有望在纯 swift 对象上工作?是否有不同的获取数据的方法,是否需要特殊的构建设置?谢谢! “帧变量”得到的结果与对象的打印描述不同。它打印几乎无用的垃圾。 @poGUIst 很不幸——你能告诉我更多关于这个的细节吗?涉及哪些数据类型? 'po' 给你什么框架变量没有? frame 变量显示成员引用的内存地址,而 'po' 执行 NSObject 后代的 'description' 方法,这通常提供更多信息。实际上我会尝试直接调用“描述”方法。可能会有所帮助。 8)【参考方案2】:我做了一些测试来弄清楚它是如何与 Swift 一起工作的,结果让我有点吃惊。使用 ObjC 对象 po
调用 debugDescription
,默认情况下调用 description
。这很清楚。不幸的是,这在使用 Swift 类时并不适用。我专注于对象而不是打印单个变量。
为了使它工作(lldb
中的po
命令),我必须覆盖描述。下面是我用于测试的代码:
class Test : NSObject
var name : String?
var surname : String?
override var debugDescription : String
return "debugDescription method"
override var description : String
return "description Method"
测试:
let test = Test()
test.name = "name"
test.surname = "surname"
(lldb) po test
description Method
(lldb) p test
(DebugTest.Test) $R1 = 0x00007fce11404860
ObjectiveC.NSObject =
isa = DebugTest.Test
name = "name"
surname = "surname"
(lldb) po dump(test)
▿ DebugTest.Test #0
- super: debugDescription method
▿ name: name
- Some: name
▿ surname: surname
- Some: surname
description Method
(lldb) po print(test)
description Method
令我惊讶的是,Swift 对象上的po
调用description
,而不是与ObjC 不同的debugDescription
。
编辑
要使其与 ObjC 一样,您的类必须实现 CustomDebugStringConvertible,然后 po
将调用 debugDescription
,默认情况下调用 description
。在我的示例中唯一需要更改的是添加:
class Test : NSObject, CustomDebugStringConvertible
Reference
与XCode 7.0.1
和ios SDK 9
、Swift 2.0
核对
【讨论】:
【参考方案3】:对于 Xcode beta4,我可以确认同样的错误,并且 框架变量-L self
显示一些东西,但看起来最糟糕:
: (SwiftCollectionViewSample.DetailViewController) self =
我会明确提交一个错误,Enrico
17819707 调试器打印错误:使用未解析的标识符“$__lldb_injected_self”
【讨论】:
【参考方案4】:本页中关于在运行lldb) po
时快速默认返回description
的精彩答案
如果它有帮助,当遇到 lldb 和 Swift 对象的错误时,我总是试图在一个好地方。
首先,告诉 lldb 你在 Swift 上下文中(不是 Objective-C):
(lldb) settings set target.language swift
然后我总是会仔细检查我是否已经导入了框架..
lldb) exp import WebKit
(lldb) expr let $ds = unsafeBitCast(0x6000006d74b0, to: WKWebsiteDataStore.self)
(lldb) po $ds
<WKWebsiteDataStore: 0x6000006d74b0>
【讨论】:
以上是关于快速在 LLDB 中使用 po的主要内容,如果未能解决你的问题,请参考以下文章
当我在 lldb 中“po”核心数据对象时,x-coredata 路径是啥意思?