What does a failing Address Sanitizer run look like to CI: exit status, ASAN_OPTIONS, and how do you read the report?
Predict first
A program reads one element past a four-element buffer under ASan. What are the exit statuses of the default run and of a run with abort disabled and a custom exit code of 7?
// === main.swift ===
let p = UnsafeMutablePointer<Int>.allocate(capacity: 4)
p.initialize(repeating: 1, count: 4)
print(p[4])
- 134 and 7
- 0 and 0
- 1 and 7
Mental model. A smoke alarm: the report is what it says, the exit status is whether the building’s fire panel noticed.
An ASan report has a fixed shape: the error kind and address (heap-buffer-overflow), the access (READ of size 8) with its stack, a line saying where the address sits relative to the allocation (“0 bytes after a 32-byte region”), the stack that allocated the region, and shadow bytes. Read it top down: the kind tells you the bug class, the first frame in your code is the access, and the allocation stack shows who owns the buffer. For a use-after-free there is a third stack for the free.
For automation the process exit status matters. In the check, the default run on macOS ends with status 134 (the sanitizer aborts, so it looks like SIGABRT), while ASAN_OPTIONS=abort_on_error=0:exitcode=7 makes it exit with 7. Setting only exitcode changes nothing here because abort wins; halt_on_error=0 additionally asks the runtime to keep going after the first report (only for builds compiled with recovery support, so do not rely on it for Swift). CI should treat any non-zero status as failure and upload the report text as an artefact. Options go in the scheme’s environment variables or the shell; the instrumented build is separate from the shipping one (Q458).
The sanitizer aborts by default on macOS; disabling abort lets exitcode apply.
Common traps
- Setting
exitcodeand expecting it to apply. On macOS the default is to abort; setabort_on_error=0too. - Reading only the access stack. The allocation (and free) stack usually names the owner that is wrong.
They might follow up with
- Which build mode? Both work;
-Onone -ggives readable frames. - Does it find logic errors? No, only memory errors on executed paths.
Related questions
- 23.3.1 What do the Address, Thread and Undefined Behavior sanitizers catch, what do they cost, and when do you use…
- 23.5.1 How do you read a crash report, what do the exception types and Swift runtime messages mean, and how does…
- 23.8.2 What does a Thread Sanitizer report look like, how does it report to CI, and why does a clean TSan run not…
What does a Thread Sanitizer report look like, how does it report to… →