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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12829665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 04:36:10  来源:igfitidea点击:

How to call methods or execute code in LLDB debugger?

xcodellvmlldb

提问by Proud Member

I know I can type print someFloatVariablewhen I set a breakpoint or po [self someIvarHoldingAnObject], but I can't do useful things like:

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

[self setAlpha:1];

Then it spits out:

然后吐出:

error: '[self' is not a valid command.

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

Weird thing is that I can call po [self someIvarHoldingAnObject]and it will print it's description.

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

I believe I've seen a video a year ago where someone demonstrated how to execute code through the console at runtime, and if I am not mistaken this guy also provided arguments and assigned objects to pointers. How to do that?

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

回答by Jason Molenda

The canonical reference for gdb v. lldb commands is http://lldb.llvm.org/lldb-gdb.html

gdb v. lldb 命令的规范参考是http://lldb.llvm.org/lldb-gdb.html

You want to use the expr command which evaluates an expression. It's one of the lldb commands that takes "raw input" in addition to arguments so you often need a "--" to indicate where the arguments (to expr) end and the command(s) begin. e.g.

您想使用计算表达式的 expr 命令。它是 lldb 命令之一,除了参数之外还接受“原始输入”,因此您通常需要一个“--”来指示参数(到 expr)结束和命令开始的位置。例如

(lldb) expr -- [self setAlpha:1]

There is a shortcut, "p", which does the -- for you (but doesn't allow any arguments), e.g.

有一个快捷方式“p”,它为您执行 -- 操作(但不允许任何参数),例如

(lldb) p [self setAlpha:1]

If the function(s) you're calling are not part of your program, you'll often need to explicitly declare their return type so lldb knows how to call them. e.g.

如果您调用的函数不是程序的一部分,您通常需要显式声明它们的返回类型,以便 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) 
@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 *);
}
= 3 hi (lldb)

There is a neat way to work around the floating point argument problem, BTW. You create an "expression prefix" file which is added to every expression you enter in lldb, with a prototype of your class methods. For instance, I have a class MyClass which inherits from NSObject, it has two methods of interest, "setArg:" and "getArg" which set and get a float ivar. This is a silly little example, but it shows how to use it. Here's a prefix file I wrote for lldb:

有一种巧妙的方法可以解决浮点参数问题,顺便说一句。您创建一个“表达式前缀”文件,该文件将添加到您在 lldb 中输入的每个表达式中,并带有类方法的原型。例如,我有一个继承自 NSObject 的类 MyClass,它有两个感兴趣的方法,“setArg:”和“getArg”,它们设置和获取浮点 ivar。这是一个愚蠢的小例子,但它展示了如何使用它。这是我为 lldb 编写的前缀文件:

settings set target.expr-prefix /Users/jason/lldb-prefix.h

in my ~/.lldbinitfile I add

在我的~/.lldbinit文件中我添加

(lldb)    p [var getArg]
(float) 
(lldb) p printf("HI\n")
<no result>
HI
(lldb) p strcmp ("HI", "THERE")
(int)  = -12
= 0.5 (lldb) p [var setArg:0.7] (id) = 0x0000000100104740 (lldb) p [var getArg] (float) = 0.7

and now I can do

现在我可以做

expression

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

// code will execute now

You'll notice I included a couple of standard C library functions in here too. After doing this, I don't need to cast the return types of these any more, e.g.

您会注意到我在这里也包含了几个标准的 C 库函数。这样做之后,我不再需要转换这些的返回类型,例如

##代码##

(a fix for that "<no result>" thing has been committed to the lldb TOT sources already.)

(已将“<no result>”问题的修复程序提交给 lldb TOT 源。)

回答by Jo?o Souza

If you need multiline, use expression:

如果您需要多行,请使用expression

##代码##

Blank line to finish and execute the code.

完成并执行代码的空行。