13

LLDB 无法处理这些语句中的任何一条...为什么无法得出 NSString 结果并打印出来

expr -o -- [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]

po [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]

问题图片在这里

4

4 回答 4

10

这更多的是学术而非实际兴趣,但最初的问题和马丁的答案实际上有不同的原因。在这两种情况下,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,编译器不喜欢向已知类添加方法,只喜欢扩展。

于 2013-10-14T19:51:20.723 回答
9

似乎 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 中的一个错误(或非功能)。

于 2013-10-12T21:53:14.200 回答
7

我在这篇文章中找到了一种解决方法: 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
于 2013-11-14T08:02:01.263 回答
7

在调试器中导入 UIKit 这对我有用

expr @import UIKit
于 2015-09-07T10:09:16.277 回答