无法在Xcode调试器中按名称解析枚举值

时间:2018-06-20 20:18:27

标签: ios objective-c xcode enums lldb

在整个项目中使用的全局头文件中都定义了枚举类型时,在Xcode中使用lldb时,我无法按名称引用单个枚举值。

例如,如果我停在任何枚举类型可用的断点处,而我尝试在Xcode的lldb提示符下评估某些内容(例如(lldb) p (int)EnumConstant),则lldb会抱怨:

error: use of undeclared identifier 'EnumConstant'

此外,如果我尝试在条件中使用枚举常量设置条件断点(例如Xcode中的右键单击断点> Edit Breakpoint ...> Condition:EnumConstant == someLocalVar),则Xcode每次都会抱怨尝试在该断点处评估该条件:

Stopped due to an error evaluating condition of breakpoint 1.1: "EnumConstant == someLocalVar"
Couldn't parse conditional expression:
error: use of undeclared identifier 'EnumConstant'

当我开始在“ Edit Breakpoint ...”窗口中键入名称时,Xcode的代码完成弹出窗口甚至可以解决对枚举常量的建议,因此Xcode本身没有问题可以解决。

是否可以在lldb或Xcode中设置一个选项,以便lldb在编译后维护枚举标识符?我假设枚举常量在编译过程中被转换为其序数值,从而导致可执行文件放弃标识符,但这只是我的幼稚推测。

当我在Linux或Cygwin的简单GNU C程序中使用等效代码(显然要减去类定义),但使用gcc / gdb而不是Xcode / lldb时,我没有这些问题。能够解决枚举值没有问题。


我创建了一个小小的Xcode iPhone项目,以演示我的意思。在enum_t上下文中使用下面的任何ViewController.m常量(for循环是演示的好地方)将产生相同的结果。

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

typedef enum
{
    eZero, eOne, eTwo, eCOUNT
}
enum_t;

extern NSString const * const ENUM_STR[];

@end

ViewController.m:

#import "ViewController.h"

@implementation ViewController

NSString const * const ENUM_STR[eCOUNT] = { @"eZero", @"eOne", @"eTwo" };

- (void)viewDidLoad
{
    [super viewDidLoad];

    for (enum_t value = eZero; value < eCOUNT; ++value)
    {
        NSLog(@"%-8@ = %d", ENUM_STR[value], value);
    }
}

@end

1 个答案:

答案 0 :(得分:4)

这是在建立名称->枚举的调试信息查找加速器表的过程中存在的错误(已相当久)。虽然列出了枚举类型,但没有列出枚举值。这样做肯定是为了节省输出调试信息的大小-调试信息很快就变得很大,因此添加更多信息的成本与该更多信息的实用程序之间始终存在紧张关系。到目前为止,还没有达到包容性的水平。

无论如何,即使对于大小合适的项目,通过“所有调试信息查找名称与'eZero'匹配的任何东西”的搜索速度也极其缓慢,而对于大型项目却非常糟糕。因此lldb始终使用这些名称->调试信息表进行第一级访问。

因为加速器表确实包含按名称列出的枚举类型(对于您也按名称键入defs更重要),所以解决方法是:

(lldb)expr enum_t :: eZero (int)$ 0 = 0

当然,如果您有真正的匿名枚举,那么在将此信息添加到加速器表之前,您很不走运。

顺便说一句,“调试器控制台”窗口中的Xcode符号完成是使用Xcode SourceKit索引器而不是lldb完成的。因此,Xcode提供的完成功能并不反映lldb对程序的了解。

BBTW,gdb不使用编译器制作的加速器表(这些是直到新的DWARF 5标准的Apple扩展),而是通过扫描调试信息来手动建立索引。这样一来,他们就可以对调试器最好的索引。 OTOH,对于大型项目,调试器的启动速度要慢得多。