如何在 LLDB 调试器中调用方法或执行代码?
Posted
技术标签:
【中文标题】如何在 LLDB 调试器中调用方法或执行代码?【英文标题】:How to call methods or execute code in LLDB debugger? 【发布时间】:2012-10-01 12:48:19 【问题描述】:我知道我可以在设置断点或po [self someIvarHoldingAnObject]
时输入print someFloatVariable
,但我不能做一些有用的事情,例如:
[self setAlpha:1];
然后吐出来:
错误:'[self' 不是有效命令。
奇怪的是我可以打电话给po [self someIvarHoldingAnObject]
,它会打印出它的描述。
我相信我在一年前看过一个视频,其中有人演示了如何在运行时通过控制台执行代码,如果我没记错的话,这个人还提供了参数并将对象分配给指针。该怎么做?
【问题讨论】:
有一个例子in lldb-for-gdb-users.txt为C:expr (int) printf ("...")
。也许你应该在你的方法调用前加上expr (type)
?
【参考方案1】:
gdb v.lldb 命令的规范参考是http://lldb.llvm.org/lldb-gdb.html
您想使用计算表达式的 expr 命令。它是除了参数之外还接受“原始输入”的 lldb 命令之一,因此您通常需要一个“--”来指示参数(到 expr)的结束位置和命令的开始位置。例如
(lldb) expr -- [self setAlpha:1]
有一个快捷方式“p”,它为您执行 -- (但不允许任何参数),例如
(lldb) p [self setAlpha:1]
如果您调用的函数不是程序的一部分,您通常需要显式声明它们的返回类型,以便 lldb 知道如何调用它们。例如
(lldb) p printf("hi\n")
error: 'printf' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (int)printf("hi\n")
(int) $0 = 3
hi
(lldb)
顺便说一句,有一种巧妙的方法可以解决浮点参数问题。您创建一个“表达式前缀”文件,该文件将添加到您在 lldb 中输入的每个表达式中,并带有您的类方法的原型。例如,我有一个继承自 NSObject 的 MyClass 类,它有两个感兴趣的方法,“setArg:”和“getArg”,它们设置和获取一个浮点 ivar。这是一个愚蠢的小例子,但它展示了如何使用它。这是我为 lldb 编写的前缀文件:
@interface NSObject
@end
@interface MyClass : NSObject
- init;
- setArg: (float)arg;
- (float) getArg;
@end
extern "C"
int strcmp (const char *, const char *);
int printf(const char * __restrict, ...);
void puts (const char *);
在我的~/.lldbinit
文件中添加
settings set target.expr-prefix /Users/jason/lldb-prefix.h
现在我可以了
(lldb) p [var getArg]
(float) $0 = 0.5
(lldb) p [var setArg:0.7]
(id) $1 = 0x0000000100104740
(lldb) p [var getArg]
(float) $2 = 0.7
您会注意到我在这里也包含了几个标准 C 库函数。完成此操作后,我不再需要转换这些返回类型,例如
(lldb) p printf("HI\n")
<no result>
HI
(lldb) p strcmp ("HI", "THERE")
(int) $3 = -12
(针对“
【讨论】:
expr -- [self setAlpha:0.5f] 或 expr -- [self setAlpha:1] 都使有问题的视图从屏幕上完全消失。似乎正在发生一些事情,但绝对不是正确的事情。我只能在设置断点时键入这些命令。或者有没有办法在代码仍在运行/未暂停时做这样的事情? 不行,你需要在调用这个方法的时候停止进程。如果此选择器采用浮点类型,则 Xcode 4.5 的 lldb 可能会遇到一个缺点——如果函数参数采用浮点类型并且您没有调试信息,则 lldb 不会为您提供任何方法将值作为浮点数传递。它将按照旧的 C 语言无原型参数提升规则无条件地将其作为双精度传递。如果 lldb 有这个类的调试信息,它应该能够做正确的事情。 ObjC 编程中出现此问题的许多实例将在以后的版本中修复。 注意:如果你遇到了我所说的 float v. double 的问题,你传递给 setAlpha 的值将不是你所期望的,它将是一些看起来很随机的疯狂数字例如,可能非常接近于 0。 “如果您调用的函数不是程序的一部分,您通常需要显式声明它们的返回类型,以便 lldb 知道如何调用它们”。谢谢!这救了我。【参考方案2】:如果需要多行,请使用expression
:
expression
do
try thing.save()
catch
print(error)
// code will execute now
空白行结束并执行代码。
【讨论】:
以上是关于如何在 LLDB 调试器中调用方法或执行代码?的主要内容,如果未能解决你的问题,请参考以下文章
在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息
android studio2.3.3 模拟器 Jni函数调用C++对象,lldb调试this指针和相关变量显示无效的原因