无法在 Xcode 调试器中按名称解析枚举值
Cannot resolve enum values by name in Xcode debugger
在整个项目中使用的全局头文件中使用了枚举类型定义,在 Xcode.
中使用 lldb 时,我无法按名称引用各个枚举值
例如,如果我在枚举类型可用的任何地方的断点处停止,并且我尝试在 Xcode(例如 (lldb) p (int)EnumConstant
)的 lldb 提示符处评估某些内容,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'
当我开始在 "Edit Breakpoint..." window 中输入名称时,Xcode 的代码完成弹出窗口甚至解决了对枚举常量的建议,因此 Xcode 本身不会解决它有问题。
有没有我可以在 lldb 或 Xcode 中设置的选项,以便 lldb 在 编译后 维护枚举标识符?我假设枚举常量在编译期间被转换为它们的序数值,导致可执行文件丢弃标识符,但这只是我天真的猜测。
当我在 Linux 或 Cygwin 中的简单 GNU C 程序中使用等效代码时(显然减去 class 定义),但使用 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
这是一个关于如何构建枚举的名称-> 调试信息查找加速器表的错误(相当长的时间)。虽然列出了枚举类型,但没有列出枚举值。这样做肯定是为了节省输出调试信息的大小——调试信息很快就会变得相当大,因此添加更多信息的成本和更多信息的效用之间一直存在紧张关系。目前这个还没有上升到包容的程度。
无论如何,通过 "all debug information for anything with a name that matches 'eZero'" 进行搜索即使对于体面大小的项目也非常慢,并且对于大型项目来说真的很糟糕。所以 lldb 总是使用这些 name->Debug Info 表来进行第一级访问。
因为加速器表确实包含按名称的枚举类型(对您来说更重要的是按名称的类型定义),解决方法是:
(lldb) 表达式 enum_t::eZero
(整数) $0 = 0
当然,如果您有真正的匿名枚举,那么在将此信息添加到加速表之前,您就很不走运了。
顺便说一句,调试器控制台 window 中的 Xcode 符号完成是使用 Xcode SourceKit 索引器完成的,而不是 lldb。因此 Xcode 提供的补全并不反映 lldb 对该程序的了解。
BBTW,gdb 不使用编译器制作的加速器表(在新的 DWARF 5 标准之前,这些是 Apple 的扩展),而是通过扫描调试信息手动构建索引。这使他们可以索引调试器认为最好的任何内容。 OTOH,它会使大型项目的调试器启动速度变慢。
在整个项目中使用的全局头文件中使用了枚举类型定义,在 Xcode.
中使用 lldb 时,我无法按名称引用各个枚举值例如,如果我在枚举类型可用的任何地方的断点处停止,并且我尝试在 Xcode(例如 (lldb) p (int)EnumConstant
)的 lldb 提示符处评估某些内容,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'
当我开始在 "Edit Breakpoint..." window 中输入名称时,Xcode 的代码完成弹出窗口甚至解决了对枚举常量的建议,因此 Xcode 本身不会解决它有问题。
有没有我可以在 lldb 或 Xcode 中设置的选项,以便 lldb 在 编译后 维护枚举标识符?我假设枚举常量在编译期间被转换为它们的序数值,导致可执行文件丢弃标识符,但这只是我天真的猜测。
当我在 Linux 或 Cygwin 中的简单 GNU C 程序中使用等效代码时(显然减去 class 定义),但使用 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
这是一个关于如何构建枚举的名称-> 调试信息查找加速器表的错误(相当长的时间)。虽然列出了枚举类型,但没有列出枚举值。这样做肯定是为了节省输出调试信息的大小——调试信息很快就会变得相当大,因此添加更多信息的成本和更多信息的效用之间一直存在紧张关系。目前这个还没有上升到包容的程度。
无论如何,通过 "all debug information for anything with a name that matches 'eZero'" 进行搜索即使对于体面大小的项目也非常慢,并且对于大型项目来说真的很糟糕。所以 lldb 总是使用这些 name->Debug Info 表来进行第一级访问。
因为加速器表确实包含按名称的枚举类型(对您来说更重要的是按名称的类型定义),解决方法是:
(lldb) 表达式 enum_t::eZero (整数) $0 = 0
当然,如果您有真正的匿名枚举,那么在将此信息添加到加速表之前,您就很不走运了。
顺便说一句,调试器控制台 window 中的 Xcode 符号完成是使用 Xcode SourceKit 索引器完成的,而不是 lldb。因此 Xcode 提供的补全并不反映 lldb 对该程序的了解。
BBTW,gdb 不使用编译器制作的加速器表(在新的 DWARF 5 标准之前,这些是 Apple 的扩展),而是通过扫描调试信息手动构建索引。这使他们可以索引调试器认为最好的任何内容。 OTOH,它会使大型项目的调试器启动速度变慢。