【问题标题】:Cannot resolve enum values by name in Xcode debugger无法在 Xcode 调试器中按名称解析枚举值
【发布时间】:2018-06-20 20:18:27
【问题描述】:

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

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

error: use of undeclared identifier 'EnumConstant'

此外,如果我尝试在条件中使用枚举常量设置条件断点(例如,在 Xcode 中右键单击断点 > 编辑断点... > 条件: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'

当我开始在“编辑断点...”窗口中输入名称时,Xcode 的代码完成弹出框甚至解决了对枚举常量的建议,因此 Xcode 本身在解决它时没有问题。

我可以在 lldb 或 Xcode 中设置一个选项,以便 lldb 在编译后维护枚举标识符?我假设枚举常量在编译期间被转换为它们的序数值,导致可执行文件丢弃标识符,但这只是我天真的猜测。

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


我创建了一个小型 Xcode iPhone 项目来说明我的意思。在ViewController.m 上下文中使用下面的任何enum_t 常量(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

【问题讨论】:

    标签: ios objective-c xcode enums lldb


    【解决方案1】:

    这是如何构建枚举的名称->调试信息查找加速器表的一个错误(相当长期)。虽然列出了枚举类型,但没有列出枚举值。这样做肯定是为了节省输出调试信息的大小 - 调试信息很快就会变得相当大,因此在添加更多信息的成本和更多信息的实用性之间存在持续的紧张关系。到目前为止,这个还没有上升到包容的水平。

    无论如何,搜索“所有调试信息以查找名称与'eZero'匹配的任何东西”即使对于体面的项目来说也非常慢,对于大型项目来说真的很糟糕。因此 lldb 始终使用这些名称->调试信息表进行第一级访问。

    因为加速器表确实包含按名称的枚举类型(对您来说更重要的是按名称键入定义),解决方法是:

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

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

    顺便说一句,调试器控制台窗口中的 Xcode 符号完成是使用 Xcode SourceKit 索引器完成的,而不是 lldb。所以 Xcode 提供的补全并不反映 lldb 对该程序的了解。

    BBTW,gdb 不使用编译器制作的加速器表(在新的 DWARF 5 标准之前,这些是 Apple 的扩展),而是通过扫描调试信息手动构建索引。这允许他们索引调试器认为最好的任何内容。 OTOH,它使大型项目的调试器启动速度相当慢。

    【讨论】:

      猜你喜欢
      • 2015-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 2017-04-23
      • 1970-01-01
      相关资源
      最近更新 更多