【问题标题】:Debug UIView(Geometry) setFrame in x86_64 lldb在 x86_64 lldb 中调试 UIView(Geometry) setFrame
【发布时间】:2016-06-06 02:22:17
【问题描述】:

在 -[UIView(Geometry) setFrame:] 上有一个符号断点 并且 lldb 在符号断点处停止,我键入了帧变量命令以产生任何结果……实际上什么都没有。

我尝试过的事情。 打开和关闭优化。 不同的拱 64 和 32

这段代码在断点之前运行

let rect =  CGRect(x: 0, y: 0, width: 320, height: 1230)
view.frame = rect

我真正想要的是在 64 位中调试 CGRect 参数,而 在 32 位 *(CGRect *)($esp + 12) 中工作正常,但在 64 位 *(CGRect *)$rdx/rcx 中错误:无法应用表达式副作用:无法解除结果变量:无法读取其内存

所以在我碰壁之后,我想看看导致我发现这一发现的框架变量。如果有人知道如何调试值

另外值得注意的是,因为 $rdx ➡ arg2 他们应该产生相同的结果,但他们没有

arg2 打印出一个 CGRect 但它的值错误

但是 $rdx 抛出错误

(lldb) po *(CGRect*)$arg2 (origin = (x = 3.8098582624090393E+180, y = 3.6806986858704324E+180), size = (width = 4.9279512391228864E+180, height = 1.469851705066036E-307)) (origin = (x = 3.8098582624090393E+180, y = 3.6806986858704324E+180), size = (width = 4.9279512391228864E+180, height = 1.469851705066036E-307)) (lldb) p *(CGRect*)$rdx error: Couldn't apply expression side effects : Couldn't dematerialize a result variable: couldn't read its memory

【问题讨论】:

  • 所以我带着这个问题去了 WWDC,在 x86_64 中,每一件事都不同,这取决于传递的类型,需要参考调用约定的文档。但在这种情况下,这里的值被卡在 xmm0,1,2,3 浮点寄存器中,正如有人在另一篇博客中指出的那样。但我从 Apple 工程师那里得到的主要观点是,如果你想知道它是如何传递的,请创建一个原型函数并对其进行反汇编,然后你就可以弄清楚它进入了哪个寄存器。
  • 嘿@DavidYangLiu,感谢您的好评。你实际上可以从中得出答案。我也在调试 `-[UIView setFrame:] 并且我找到了 $arg6 来保存框架。
  • @DavidYangLiu 您能否再解释一下在 setFrame 符号框架的情况下如何从 xmm0...3 实际获取该值。还有原型函数的实际含义以及如何使用它来研究它?我缺少一些知识,但很好奇它是如何真正起作用的。

标签: xcode debugging lldb


【解决方案1】:

x86_64 ($arg1) 上的函数的第一个参数在 rdi 中传递。 x86_64 ($arg2) 上的函数的第二个参数在rsi 中传递。第三个参数是rdx。我怀疑这是您在将其作为值传递给 p 时看到的问题的根源。

frame variable(简称fr v)只显示带有调试信息的变量。您在没有调试信息的普通汇编函数中停止。在第一个 pc 值中,第一个参数在 rdi 中,第二个在 `rsi 中,等等,lldb 可以将这些显示为“变量” - 但是一旦你逐步执行函数,这些寄存器可能会被重用对于其他值(例如,如果调用另一个函数),因此不再安全地说该寄存器中的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多