代码之家  ›  专栏  ›  技术社区  ›  ardnew

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

  •  1
  • ardnew  · 技术社区  · 8 年前

    由于在整个项目中使用了全局头文件中的枚举typedef,所以在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'
    

    XCODEL的代码完成POPORE甚至解决了在“编辑断点…”窗口中键入名称时EnUM常量的建议,因此XCODEL本身不存在解决它的问题。

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

    当我在Linux或CygWin的简单GNU C程序中使用等效代码时(明显减去类定义),但是使用Gcc/GDB而不是XCOD/LLDB,我不存在这些问题。它能够解决枚举值没有问题。


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

    视图控制器.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 回复  |  直到 8 年前
        1
  •  4
  •   Jim Ingham    8 年前

    这是一个bug(相当长的时间),用于枚举的name->debug information lookup accelerator表是如何构建的。列出枚举类型时,不列出枚举值。这确实是为了节省输出调试信息大小-调试信息变得相当大很快,因此有一个不断增加的信息之间的紧张关系和更多的信息的效用。到目前为止,这个还没有上升到包容的程度。

    无论如何,在“所有调试信息中搜索与‘ezero’匹配的任何名称”的过程都会非常缓慢,即使是对于大小合适的项目也是如此,对于大型项目来说也会变得非常糟糕。因此,lldb总是使用这些名称->调试信息表进行第一级访问。

    因为加速器表按名称包含EnUM类型(而且对于名称也更重要),解决方法是:

    (lldb)表达式枚举::ezero (int)0美元=0

    当然,如果你有真正的匿名枚举,那么你很不走运,直到这个信息被添加到加速器表。

    顺便说一句,调试器控制台窗口中的xcode符号完成是使用xcode sourcekit索引器而不是lldb完成的。因此,xcode提供的补全并不是lldb对程序知识的反映。

    gdb不使用编译器生成的加速表(在新的dwarf 5标准之前,这是apple的扩展),而是通过扫描调试信息手动构建索引。这使得它们可以为调试器认为最好的东西建立索引。OTHH,它使得调试器启动对于大型项目来说有点慢。