Debug vs. Release Builds
A debug build includes symbols that can be used by a debugger to display your source code when your program stops at a breakpoint and to show you the values of your variables at that point. For a release build, you normally want to strip that information out, because the debug information makes it very easy to reverse-engineer the program. Release builds also typically do code optimization that isn’t done for debug builds. Because the Run action is normally used for debugging, most developers use a debug build configuration for the Run action. However, you might occasionally want to build and run your application with the release configuration to see what size your application will be and to make sure there are no problems introduced by the code optimization; that is, to make sure your application runs as you expect.
Memory Management options:
-
Enable Scribble. Fill allocated memory with
0xAA
and deallocated memory with0x55
. -
Enable Guard Edges. Add guard pages before and after large allocations.
-
Enable Guard Malloc. Use
libgmalloc
to catch common memory problems such as buffer overruns and use-after-free. -
Enable Zombie Objects. Replace deallocated objects with a “zombie” object that traps any attempt to use it. When you send a message to a zombie object, the runtime logs an error and crashes. You can look at the backtrace to see the chain of calls that triggered the zombie detector.
Logging options:
-
Distributed Objects. Enable logging for distributed objects (
NSConnection
,NSInvocation
,NSDistantObject
, andNSConcretePortCoder
). -
Garbage Collection Activity. Enable various logging facilities in the garbage-collected memory allocator. Log when a collection occurs, log when new regions are allocated, and log all weak reference manipulations.
-
Malloc Stack. Record stack logs for memory allocations and deallocations.
-
Log Exceptions. Log Objective-C runtime exception handling.
-
Log DYLD API Usage. Log dynamic-linker API calls (for example,
dlopen
). -
Log Library Loads. Log dynamic-linker library loads.
Debugger options:
-
Stop on Debugger() and DebugStr(). Enable Core Services routines that enter the debugger with a message. These routines send a SIGINT signal to the current process.
The Xcode static analyzer parses the project source code and identifies these types of problems:
-
Logic flaws, such as accessing uninitialized variables and dereferencing null pointers
-
Memory management flaws, such as leaking allocated memory
-
Dead store (unused variable) flaws
-
API-usage flaws that result from not following the policies required by the frameworks and libraries the project is using