<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v" -->

---
title: The Sanitizers Handbook: Memory, Initialization, and Races
description: A deep-dive handbook on the four LLVM sanitizers—AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer—explaining what runtime property each...
canonical: https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The Sanitizers Handbook: Memory, Initialization, and Races | daily.dev
og:description: A deep-dive handbook on the four LLVM sanitizers—AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer—explaining what runtime property each...
og:url: https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v
og:image: https://api.daily.dev/og/posts/3HZWTJ43v.png
og:image:alt: The Sanitizers Handbook: Memory, Initialization, and Races
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The Sanitizers Handbook: Memory, Initialization, and Races

**[freeCodeCamp](https://daily.dev/sources/freecodecamp)** · 96 min read · 0 upvotes · 0 comments

## Summary

A deep-dive handbook on the four LLVM sanitizers—AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer—explaining what runtime property each one checks and why passing functional tests can still hide invalid execution. It covers ASan's shadow memory model for addressability and lifetime bugs, LSan's terminal ownership accounting via reachability at teardown, MSan's initialization provenance tracking across API boundaries, and TSan's happens-before reconstruction for data races. Throughout, it emphasizes that sanitizers only report violations in executions they actually observe, so workload design (fuzzing, stress tests, lifecycle cycling) and instrumentation coverage across FFI boundaries (e.g. Dart's webcrypto.dart wrapping BoringSSL) determine how trustworthy a clean run really is. Practical build flags, suppression policy, and CI placement guidance are included for each tool.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.freecodecamp.org/news/the-sanitizers-handbook>

## Questions this post answers

### What is the difference between AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer?

Each tool checks a different runtime contract: AddressSanitizer (ASan) tracks addressability and lifetime, catching use-after-free and out-of-bounds access; LeakSanitizer (LSan) performs terminal ownership accounting at process teardown to find unreachable allocations; MemorySanitizer (MSan) tracks initialization provenance to catch uninitialized values influencing execution; ThreadSanitizer (TSan) reconstructs happens-before relationships to detect unordered conflicting accesses across threads.

_Comparing memory-safety tools before adding one to a build is easier with daily.dev's technical breakdowns on hand._

### Why can't sanitizer tooling catch every use-after-free or race condition even in a clean run?

A sanitizer can only report a violation that occurs during an observed execution and within instrumented code. ASan can't catch a stale pointer nobody dereferences, TSan can't report a race if conflicting accesses never overlap, and MSan loses initialization history when execution passes through uninstrumented libraries, custom allocators, or opaque dependencies, so workload design matters as much as the compiler flag.

_Developers hardening native and FFI code against hidden lifetime bugs can track these workload-design tactics on daily.dev._

### How should BoringSSL-style get0/get1/set0/set1 naming conventions guide FFI wrapper ownership design?

These conventions distinguish borrowed references (get0), owned references (get1), ownership-transferring operations (set0), and reference-retaining operations (set1); a wrapper that collapses all of them into one generic pointer type discards the ownership information the native API deliberately preserves, leading to freed borrowed handles, reused transferred handles, or leaked retained references. Explicit borrow/take/clone_ref-style methods in the wrapper preserve that distinction.

_Teams designing safer FFI wrappers around native libraries can follow ownership patterns like these on daily.dev._

## Similar posts on daily.dev

- [BorrowSanitizer](https://daily.dev/posts/borrowsanitizer-4ckct9kas) · Lobsters · 0 upvotes · 0 comments
- [Poison, redzones and shadows: inside KASAN – Bootlin](https://daily.dev/posts/poison-redzones-and-shadows-inside-kasan-bootlin-hgaakzhee) · Bootlin · 0 upvotes · 0 comments
- [Better Bug Detection: How Compile-Time Instrumentation for Compute Sanitizer Enhances Memory Safety](https://daily.dev/posts/better-bug-detection-how-compile-time-instrumentation-for-compute-sanitizer-enhances-memory-safety-toosw4cqy) · NVIDIA Developer · 0 upvotes · 0 comments

---

Tags: [#general-programming](https://daily.dev/tags/general-programming)

[View this post on daily.dev](https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The Sanitizers Handbook: Memory, Initialization, and Races","url":"https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v"},"datePublished":"2026-08-21T20:16:58.757Z","dateModified":"2026-09-13T20:10:05.272Z","description":"A deep-dive handbook on the four LLVM sanitizers—AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer—explaining what runtime property each...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3ecfff7337fcdb68f72c3a88303c327f?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3ecfff7337fcdb68f72c3a88303c327f?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"freeCodeCamp","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"freeCodeCamp","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1628412854/logos/freecodecamp","url":"https://daily.dev/sources/freecodecamp"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"general-programming","timeRequired":"PT96M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"freeCodeCamp","item":"https://daily.dev/sources/freecodecamp"},{"@type":"ListItem","position":3,"name":"The Sanitizers Handbook: Memory, Initialization, and Races"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/the-sanitizers-handbook-memory-initialization-and-races-3hzwtj43v#faq","mainEntity":[{"@type":"Question","name":"What is the difference between AddressSanitizer, LeakSanitizer, MemorySanitizer, and ThreadSanitizer?","acceptedAnswer":{"@type":"Answer","text":"Each tool checks a different runtime contract: AddressSanitizer (ASan) tracks addressability and lifetime, catching use-after-free and out-of-bounds access; LeakSanitizer (LSan) performs terminal ownership accounting at process teardown to find unreachable allocations; MemorySanitizer (MSan) tracks initialization provenance to catch uninitialized values influencing execution; ThreadSanitizer (TSan) reconstructs happens-before relationships to detect unordered conflicting accesses across threads. Comparing memory-safety tools before adding one to a build is easier with daily.dev's technical breakdowns on hand."}},{"@type":"Question","name":"Why can't sanitizer tooling catch every use-after-free or race condition even in a clean run?","acceptedAnswer":{"@type":"Answer","text":"A sanitizer can only report a violation that occurs during an observed execution and within instrumented code. ASan can't catch a stale pointer nobody dereferences, TSan can't report a race if conflicting accesses never overlap, and MSan loses initialization history when execution passes through uninstrumented libraries, custom allocators, or opaque dependencies, so workload design matters as much as the compiler flag. Developers hardening native and FFI code against hidden lifetime bugs can track these workload-design tactics on daily.dev."}},{"@type":"Question","name":"How should BoringSSL-style get0/get1/set0/set1 naming conventions guide FFI wrapper ownership design?","acceptedAnswer":{"@type":"Answer","text":"These conventions distinguish borrowed references (get0), owned references (get1), ownership-transferring operations (set0), and reference-retaining operations (set1); a wrapper that collapses all of them into one generic pointer type discards the ownership information the native API deliberately preserves, leading to freed borrowed handles, reused transferred handles, or leaked retained references. Explicit borrow/take/clone_ref-style methods in the wrapper preserve that distinction. Teams designing safer FFI wrappers around native libraries can follow ownership patterns like these on daily.dev."}}]}
```

