1---
  2title: Using Address Sanitizer with clang
  3url: using-address-sanitizer-with-clang.html
  4date: 2026-01-15T16:13:13+02:00
  5type: post
  6draft: false
  7tags: []
  8---
  9
 10## What -fsanitize=address does
 11
 12- Enables AddressSanitizer (ASan): a compile and link time instrumentation plus
 13  runtime library that detects memory errors.
 14- Detects: out-of-bounds accesses (heap, stack, globals), use-after-free, some
 15  use-after-return, double/invalid free, and (on some platforms) leaks.
 16- How it works: instrumented memory accesses are checked against a shadow
 17  memory; violations produce an error report with a stack trace and abort the
 18  program.
 19- Trade-offs: ~2x runtime slowdown (varies), higher memory use, large virtual
 20  address space reservation on 64-bit, and requires linking the ASan runtime
 21  (not suitable for production builds).
 22- Usage: compile and link with `-fsanitize=address` (and typically `-g` and
 23  `-O0`). Runtime behavior can be tuned via `ASAN_OPTIONS` and
 24  symbolization via llvm-symbolizer.
 25
 26More about ASan on https://clang.llvm.org/docs/AddressSanitizer.html.
 27
 28## An example how to use it
 29
 30```c
 31#include <stdlib.h>
 32#include <stdio.h>
 33#include <string.h>
 34
 35int main(void) {
 36    char *p = malloc(10);
 37    if (!p) return 1;
 38
 39    // Out-of-bounds write (heap buffer overflow).
 40    strcpy(p, "This string is way too long for the buffer");
 41
 42    // Use-after-free (unreachable if program aborts on previous error).
 43    free(p);
 44    p[0] = 'x';
 45
 46    return 0;
 47}
 48```
 49
 50Now let's compile with proper flags with `clang -O0 -g -fsanitize=address -o
 51main main.c`.
 52
 53If you run the binary it should trigger ASan.  You can also specify what to
 54show with `ASAN_OPTIONS=detect_leaks=1:verbosity=1:symbolize=1 ./main` and you
 55should see something like this.
 56
 57```text
 58MemToShadow(shadow): 0x00008fff7000 0x000091ff6dff 0x004091ff6e00 0x02008fff6fff
 59redzone=16
 60max_redzone=2048
 61quarantine_size_mb=256M
 62thread_local_quarantine_size_kb=1024K
 63malloc_context_size=30
 64SHADOW_SCALE: 3
 65SHADOW_GRANULARITY: 8
 66SHADOW_OFFSET: 0x00007fff8000
 67==28825==Installed the sigaction for signal 11
 68==28825==Installed the sigaction for signal 7
 69==28825==Installed the sigaction for signal 8
 70==28825==T0: FakeStack created: 0x7be4d10f7000 -- 0x7be4d1c00000 stack_size_log: 20; mmapped 11300K, noreserve=0
 71==28825==T0: stack [0x7ffcf551c000,0x7ffcf5d1c000) size 0x800000; local=0x7ffcf5d1a664
 72==28825==AddressSanitizer Init done
 73=================================================================
 74==28825==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c04d25e001a at pc 0x5653c583826a bp 0x7ffcf5d1a5f0 sp 0x7ffcf5d19da8
 75WRITE of size 43 at 0x7c04d25e001a thread T0
 76    #0 0x5653c5838269 in strcpy (/home/m/Junk/fsanitize/main+0xb7269) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a)
 77    #1 0x5653c5894e13 in main /home/m/Junk/fsanitize/main.c:10:5
 78    #2 0x7fe4d328bbfb in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
 79    #3 0x7fe4d328bcb4 in __libc_start_main@GLIBC_2.2.5 csu/../csu/libc-start.c:360:3
 80    #4 0x5653c57ad360 in _start /builddir/glibc-2.41/csu/../sysdeps/x86_64/start.S:115
 81
 820x7c04d25e001a is located 0 bytes after 10-byte region [0x7c04d25e0010,0x7c04d25e001a)
 83allocated by thread T0 here:
 84    #0 0x5653c5851ca4 in malloc (/home/m/Junk/fsanitize/main+0xd0ca4) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a)
 85    #1 0x5653c5894de8 in main /home/m/Junk/fsanitize/main.c:6:15
 86    #2 0x7fe4d328bbfb in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
 87
 88SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/m/Junk/fsanitize/main+0xb7269) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a) in strcpy
 89Shadow bytes around the buggy address:
 90  0x7c04d25dfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 91  0x7c04d25dfe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 92  0x7c04d25dfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 93  0x7c04d25dff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 94  0x7c04d25dff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 95=>0x7c04d25e0000: fa fa 00[02]fa fa fa fa fa fa fa fa fa fa fa fa
 96  0x7c04d25e0080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 97  0x7c04d25e0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 98  0x7c04d25e0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 99  0x7c04d25e0200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
100  0x7c04d25e0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
101Shadow byte legend (one shadow byte represents 8 application bytes):
102  Addressable:           00
103  Partially addressable: 01 02 03 04 05 06 07
104  Heap left redzone:       fa
105  Freed heap region:       fd
106  Stack left redzone:      f1
107  Stack mid redzone:       f2
108  Stack right redzone:     f3
109  Stack after return:      f5
110  Stack use after scope:   f8
111  Global redzone:          f9
112  Global init order:       f6
113  Poisoned by user:        f7
114  Container overflow:      fc
115  Array cookie:            ac
116  Intra object redzone:    bb
117  ASan internal:           fe
118  Left alloca redzone:     ca
119  Right alloca redzone:    cb
120==28825==ABORTING
121```