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


70

我知道print someFloatVariable在设置断点或时可以键入po [self someIvarHoldingAnObject],但是我不能做一些有用的事情,例如:

[self setAlpha:1];

然后它吐出:

错误:“ [self”不是有效命令。

奇怪的是我可以打电话给我po [self someIvarHoldingAnObject],它会打印出它的描述。

我相信我一年前看过一个视频,其中有人演示了如何在运行时通过控制台执行代码,如果我没有记错的话,这个人还提供了参数并为指针分配了对象。怎么做?


lldb-for-gdb-users.txt中有一个C:的示例expr (int) printf ("...")。也许您应该在方法调用之前添加前缀expr (type)
osgx 2012年

Answers:


113

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)

有一种巧妙的方法可以解决浮点参数问题BTW。您创建一个“表达式前缀”文件,该文件会添加到您在lldb中输入的每个表达式中,并带有类方法的原型。例如,我有一个MyClass类,它继承自NSObject,它有两个有趣的方法,即“ setArg:”和“ getArg”,它们设置并获取一个float 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

(针对“ <no result>”问题的修复已提交至lldb TOT源。)


expr-[self setAlpha:0.5f]或expr-[self setAlpha:1]都可以使所讨论的视图从屏幕上完全消失。似乎正在发生某些事情,但绝对不是正确的事情。我只能在设置断点时键入这些命令。还是有办法在代码仍在运行/未暂停的情况下执行此类操作?
骄傲的会员

不,您需要在调用此方法时停止该过程。如果此选择器采用浮点类型,则可能会遇到Xcode 4.5的lldb的缺点-如果function参数采用浮点类型并且您没有调试信息,则lldb不会给您任何方法将值作为浮点数传递。它将遵循旧的C语言无原型参数提升规则,无条件地将其作为double传递。如果lldb具有此类的调试信息,则它应该能够做正确的事情。ObjC编程中此问题的许多实例将在将来的版本中修复。
詹森·莫伦达

注意:如果您遇到的问题是float v。double,那么传递给setAlpha的值将不是您期望的值,而是一些看起来很疯狂的随机数,可能非常接近0,因为实例。
杰森·莫伦达

“如果要调用的函数不属于程序的一部分,则通常需要显式声明其返回类型,以便lldb知道如何调用它们”。谢谢!那救了我。
kakyo

5

如果需要多行,请使用expression

expression

do {
  try thing.save()
} catch {
  print(error)
}

// code will execute now

空行以完成并执行代码。

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.