Fundamentals 15 min read

How AddressSanitizer Detects Memory Errors: Inside Its Shadow Memory and Redzones

This article explains the core algorithms behind AddressSanitizer, covering its shadow memory mapping, instrumentation module, runtime library, poisoned redzones, false‑negative scenarios, configurable flags, and emerging hardware‑assisted designs for memory‑error detection.

NetEase Smart Enterprise Tech+
NetEase Smart Enterprise Tech+
NetEase Smart Enterprise Tech+
How AddressSanitizer Detects Memory Errors: Inside Its Shadow Memory and Redzones

ASan Principle

ASan determines whether a memory access is valid by maintaining a shadow memory that stores a poison state for each byte of application memory. Before each access, the shadow byte is checked; if poisoned, an error is reported.

Components

Instrumentation module – at compile time it transforms every memory access, adds poisoned redzones around stack and global objects.

Run‑time library – provides a custom allocator that replaces malloc/free, creates poisoned redzones around heap objects, delays reuse of freed memory, and manages shadow memory.

Shadow Memory

Application memory (Mem) and shadow memory (Shadow) have a 1‑to‑8 mapping: each 8‑byte block of Mem corresponds to one byte in Shadow that encodes the poison state. The mapping uses the formula (Addr>>Scale)+Offset with Scale = 3 and platform‑specific Offset values (e.g., 0x20000000 on 32‑bit Linux, 0x0000100000000000 on 64‑bit).

Encoding

0 – all 8 bytes are addressable.

k (1‑7) – first k bytes are addressable.

Negative values – the whole 8‑byte block is poisoned (heap, stack, global redzones, or freed memory).

Instrumentation

During compilation, each memory access is replaced with code that looks up the corresponding shadow byte and, if non‑zero, calls a slow‑path check before performing the original operation.

byte *shadow_address = MemToShadow(address);
byte shadow_value = *shadow_address;
if (shadow_value) {
    if (SlowPathCheck(shadow_value, address, kAccessSize)) {
        ReportError(address, kAccessSize, kIsWrite);
    }
}
*address = ...; // original write
variable = *address; // original read

Poisoned Redzones

Redzones are memory regions filled with poisoned bytes placed around stack, global, and heap objects. Accessing a redzone triggers an ASan error, helping detect out‑of‑bounds writes, use‑after‑free, and other bugs.

False Negatives

ASan may miss errors such as partially out‑of‑bounds unaligned accesses, very distant out‑of‑bounds writes beyond redzones, and use‑after‑free bugs when the quarantine queue is exhausted.

Runtime Flags

malloc_context_size – depth of stack trace for malloc/free (default 30).

quarantine_size_mb – size of the quarantine area (default 256 MiB).

redzone / max_redzone – size of heap poisoned redzone (default 128 bytes).

Hardware‑Assisted ASan

Future designs propose a hardware instruction checkN Addr that performs the shadow lookup and validation in a single step, reducing overhead and binary size.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingMemory SafetyC++Shadow MemoryRuntime InstrumentationAddressSanitizer
NetEase Smart Enterprise Tech+
Written by

NetEase Smart Enterprise Tech+

Get cutting-edge insights from NetEase's CTO, access the most valuable tech knowledge, and learn NetEase's latest best practices. NetEase Smart Enterprise Tech+ helps you grow from a thinker into a tech expert.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.