为什么LLDB不能评估这个表达式?

时间:2013-10-12 21:42:53

标签: objective-c nsstring lldb

LLDB无法处理这些陈述中的任何一个......为什么它无法提出NSString结果并将其打印出来

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

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

Picture of problem here

4 个答案:

答案 0 :(得分:8)

似乎lldb中的表达式命令通常不能用它来计算函数 变量参数列表。即使使用简单的C函数也会失败:

int foo(char *msg, ...)
{
    return 17;
}
(lldb) expr foo("bar")
(int) $2 = 17

(lldb) expr foo("bar", 2)
error: no matching function for call to 'foo'
note: candidate function not viable: requires 1 argument, but 2 were provided
error: 1 errors parsing expression

所以这看起来像lldb中的错误(或非特征)。

答案 1 :(得分:8)

这更多是学术上的而不是实际的兴趣,但最初的问题和马丁的答案实际上有不同的原因。在这两种情况下,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

然后你可以在表达式解析器中调用该函数。有这个功能的几个警告。这个“表达式前缀”文件包含在你使用“print”命令运行的所有表达式中,所以不要在那里放太多东西,否则会减慢一般表达式解析。不要尝试做以下事情:

#import <Cocoa/Cocoa.h>

这将非常慢并且可能无论如何都不会起作用 - 因为这取决于调试器不知道的整组#defines。

但如果你有一些你真正需要调用的函数,那会非常有用,但不能因为我们要么不知道签名,要么以某种方式弄错了。

extern“C”是必需的,因为lldb将表达式解析为ObjC ++。

如果你想要一个ObjC方法的原型,你需要在你为该方法原型设计的类的扩展上进行;我们经常有一个基本类def'n,并且编译器不喜欢将方法添加到已知类,只是扩展。

答案 2 :(得分: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

答案 3 :(得分:5)

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

expr @import UIKit