views:

28

answers:

1

I would like to create some environment viables in Xcode for heavy debugging such as:

  NSDebugEnabled
  NSZombieEnabled
  MallocStackLogging
  MallocStackLoggingNoCompact

Is it possible to create a new build configuration that is a duplicate of "Debug" where those environmental variables are set to YES, but i can just switch to regular Debug and those would be off again?


A: 

IIRC, Environment variables are set in the "executable", not the configuration/target (ignore this rant if I'm wrong). You might be able to use Xcode variable substitution:

  • Create a boolean build setting called "NSDebugEnabled". Set the NSDebugEnabled environment variable to $(NSDebugEnabled). (It might have to be a string with the value YES; I'm not sure how picky the NS environment variables are.)
  • Create a string build setting called "NSDebugEnabled". Set it to "NSDebugEnabled" to enable and something else (the empty string?) to disable. Use $(NSDebugEnable) as the environment variable name and "YES" as the value.

If variable substitution doesn't work, you might be able to call setenv()/putenv() at the very start of main() (before allocating an autorelease pool) to alter the environment before the variables are read; whether this is successful depends on when they're read. IIRC malloc() reads them the first time you call malloc() (this might be very early due to Obj-C runtime/+load methods). I'm not sure when the NS* ones are read.

If that still doesn't work, and you're happy running in the simulator, I think you can use 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() ...
}

I'm pretty sure the execve() system call is prohibited by sandboxing on device.


If all that's too much, here's what I do:

Add some environment variables to the executable. Uncheck the checkbox. When debugging is required, check the checkboxes. When debugging is finished, uncheck them. Before committing, check that you aren't committing anything silly in the .xcodeproj.

I don't think you need MallocStackLogging if you use Leaks (Leaks should set it automatically).

You might also consider MallocPreScribble and MallocScribble.

tc.
Hi, I like the final option.You're right the above is too much, it's much simpler in terms of mental juggling, to just uncheck those boxes.
Onedayitwillmake