【问题标题】:Conditional Environment Variables in XcodeXcode 中的条件环境变量
【发布时间】:2011-04-18 11:38:21
【问题描述】:

我想在 Xcode 中创建一些可行的环境来进行繁重的调试,例如:

  NSDebugEnabled
  NSZombieEnabled
  MallocStackLogging
  MallocStackLoggingNoCompact

是否可以创建一个与“调试”重复的新构建配置,其中那些环境变量设置为“是”,但我可以切换到常规调试,而那些会再次关闭?


【问题讨论】:

    标签: iphone xcode debugging ios


    【解决方案1】:

    IIRC,环境变量设置在“可执行文件”中,而不是配置/目标(如果我错了,请忽略此咆哮)。您也许可以使用 Xcode 变量替换:

    • 创建一个名为“NSDebugEnabled”的布尔构建设置。将 NSDebugEnabled 环境变量设置为 $(NSDebugEnabled)。 (它可能必须是一个值为 YES 的字符串;我不确定 NS 环境变量有多挑剔。)
    • 创建一个名为“NSDebugEnabled”的字符串构建设置。将其设置为“NSDebugEnabled”以启用,将其他内容(空字符串?)设置为禁用。使用 $(NSDebugEnable) 作为环境变量名,使用“YES”作为值。

    如果变量替换不起作用,您也许可以在 main() 的一开始(在分配自动释放池之前)调用 setenv()/putenv() 来改变环境在读取变量之前;这是否成功取决于何时阅读。 IIRC malloc() 在您第一次调用 malloc() 时读取它们(由于 Obj-C 运行时/+load 方法,这可能很早)。我不确定何时读取 NS*。

    如果这仍然不起作用,并且您很高兴在模拟器中运行,我认为您可以使用 execve():

    #include <unistd.h>
    
    int main (int argc, char ** argv, char ** envp)
    {
    #ifdef DEBUGENVIRON
      if (!getenv("NSDebugEnabled"))
      {
        setenv("NSDebugEnabled","1",1);
        ... set the other variables ...
        // Maybe this will complain about an autorelease pool.
        char * executablePath = [[[NSBundle mainBundle] executablePath] filesystemRepresentation];
        execve(executablePath, argv, environ); abort();
      }
    #endif
      ... do what you normally do in main() ...
    }
    

    我很确定设备上的沙盒禁止了 execve() 系统调用。


    如果这太多了,这就是我要做的:

    向可执行文件添加一些环境变量。取消选中复选框。需要调试时,选中复选框。调试完成后,取消选中它们。在提交之前,请检查您没有在 .xcodeproj 中提交任何愚蠢的内容。

    如果您使用 Leaks,我认为您不需要 MallocStackLogging(Leaks 应该自动设置它)。

    您也可以考虑 MallocPreScribble 和 MallocScribble。

    【讨论】:

    • 嗨,我喜欢最后一个选项。你说得对,上面的内容太多了,在心理杂耍方面要简单得多,只需取消选中这些框即可。
    猜你喜欢
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 2013-01-11
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多