LLDB 无法处理这些语句中的任何一条...为什么无法得出 NSString 结果并打印出来
expr -o -- [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
po [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
LLDB 无法处理这些语句中的任何一条...为什么无法得出 NSString 结果并打印出来
expr -o -- [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
po [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
这更多的是学术而非实际兴趣,但最初的问题和马丁的答案实际上有不同的原因。在这两种情况下,lldb 实际上都正确地拒绝调用具有比声明的参数更多的函数,但由于不同的原因导致实际定义错误。
在第一种情况下,lldb 实际上没有方法调用 [NSString stringWithFormat:format, ...] 的调试信息。事实证明,编译器不会为程序使用的每个函数发出调试信息,只会为它定义的函数发出调试信息。这个限制主要是为了保持调试信息的大小易于管理。
因此,调试器必须咨询 ObjC 运行时以获取这些套件功能的额外类型信息。但是运行时类型信息不编码可变参数函数的可变参数。
在第二种情况下,您看到的实际上是 clang 调试输出中的一个错误。它无法发出告诉调试器该函数是可变参数函数的信息。
无论如何,在 lldb 中,您可以通过使用“expr-prefix”文件将常用函数的声明引入 lldb 的表达式解析器来解决此类问题。例如,在 Martin 的例子中,我创建了一个文件“/tmp/expr-prefix.lldb”,其中包含以下行:
extern "C" int foo (char *msg, ...);
然后在lldb中,我这样做:
(lldb) settings set target.expr-prefix /tmp/expr-prefix.lldb
然后您可以在表达式解析器中调用该函数。此功能有几个注意事项。这个“表达式前缀”文件包含在您使用“打印”命令运行的所有表达式中,所以不要在里面放太多东西,否则会减慢一般表达式的解析速度。不要试图做这样的事情:
#import <Cocoa/Cocoa.h>
这将非常慢并且可能无论如何都不会工作 - 因为这取决于调试器不知道的一整套#defines。
但是,如果您确实需要调用一些像这样的函数,但由于我们不知道签名或者以某种方式弄错了,所以不能调用它,这会很有帮助。
extern "C" 是必需的,因为 lldb 将表达式解析为 ObjC++。
如果您想为 ObjC 方法制作原型,您需要在您为其制作原型的类的扩展上进行;我们经常有一个基本的类def'n,编译器不喜欢向已知类添加方法,只喜欢扩展。
似乎 lldb 中的表达式命令通常无法评估具有可变参数列表的函数。即使使用简单的 C 函数,它也会失败:
int foo(char *msg, ...)
{
return 17;
}
(lldb) expr foo("bar") (int) $2 = 17 (lldb) expr foo("bar", 2) 错误:没有匹配的函数调用“foo” 注意:候选函数不可行:需要 1 个参数,但提供了 2 个 error: 1 解析表达式错误
所以这看起来像是 lldb 中的一个错误(或非功能)。
我在这篇文章中找到了一种解决方法: http ://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/
例如,当我尝试使用此语法调用方法时:
po [NSString stringWithFormat:@"%@", @"MyName"];
调试器错误是:
error: too many arguments to method call, expected 1, have 2
error: 1 errors parsing expression
但是你可以试试这个:
po [[NSString alloc] initWithFormat:@"%@", @"MyName"];
调试器消息是:
$4 = 0x0a6737f0 MyName
在调试器中导入 UIKit 这对我有用
expr @import UIKit