快速在 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.1ios SDK 9Swift 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的主要内容,如果未能解决你的问题,请参考以下文章

IOS调试lldb命令常用po

LLDB常用调试命令

当我在 lldb 中“po”核心数据对象时,x-coredata 路径是啥意思?

如何在带有 Swift 的 LLDB 控制台中使用 _printHierarchy?

如何在 LLDB 调试器中调用方法或执行代码?

查看视图层级关系