Using the Address Sanitizer

If you are struggling to debug a memory corruption problem you may want to take a look at the Address Sanitizer introduced with Xcode 7.

Enabling the Address Sanitizer

To use the Address Sanitizer you need to edit the scheme (from the Product menu select Scheme > Edit Scheme...). Then for the Run command select the Diagnostics tab and check the Enable Address Sanitizer option:

Enable Address Sanitizer

It works for both the Simulator and on devices after a recompilation. You should also use a compiler optimization level of None [-O0] or at most Fast [-O1].

Example Output

A trivial example to show how it works when we mistakenly access beyond the end of a memory buffer:

- (void)viewDidLoad {
  [super viewDidLoad];
  char *buffer = malloc(80);
  buffer[80] = 'Y';

When the address sanitizer detects the invalid access the debugger breaks and it writes an extensive report to the console (I have truncated the output here):

==6726==ERROR: AddressSanitizer: heap-buffer-overflow on address 
0x607000024ea0 at pc 0x00010a8aff0c bp 0x7fff5534d9e0 sp 0x7fff5534d9d8
WRITE of size 1 at 0x607000024ea0 thread T0
SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 -[ViewController viewDidLoad]
Shadow bytes around the buggy address:
0x1c0e00004980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

The detailed report can be a little cryptic to understand. Luckily Xcode integrates the Address Sanitizer into the Debug Navigator so that you can quickly see the call stack and the offending line of code:

Debug Navigator

You can also view the history of the corrupted memory in the lower section of the Debug Navigator.

When to Use

It is important to understand that the Address Sanitizer is a run-time tool so you need to exercise your code for it to find problems. This makes it a good candidate to enable when running unit and UI tests. Whilst Apple claims it has low overhead (2x-5x CPU and 2x-3x memory) it is not performance free so you may want to experiment if you have large test suites before leaving it enabled.

Enable the Address Sanitizer for testing as before by editing the Scheme and this time enable it for the Test command:

Enable Address Sanitizer

For some extra background reading on how the Address Sanitizer works: