Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Duckdb Duckdb Sanitizer Configuration

From Leeroopedia




Knowledge Sources
Domains Debugging, Build_System
Last Updated 2026-02-07 12:00 GMT

Overview

Address Sanitizer (ASAN) and Thread Sanitizer (TSAN) are mutually exclusive in DuckDB; enabling both silently disables ASAN. M1 MacBooks need vptr sanitizer workaround with older Clang.

Description

DuckDB enables AddressSanitizer and UndefinedBehaviorSanitizer by default in debug builds. However, ASAN and TSAN cannot coexist (a GCC/Clang limitation), and UBSAN also conflicts with TSAN. The build system handles these conflicts automatically but silently, which can lead to confusion. Additionally, the vptr sanitizer produces false positives on Apple M1 (ARM64) machines with Clang versions below 14.0.

Usage

Apply this heuristic when debugging memory issues (use ASAN), debugging race conditions (use TSAN), or when encountering false positive sanitizer reports on M1 MacBooks. Understanding the mutual exclusivity prevents wasted debugging time with the wrong sanitizer enabled.

The Insight (Rule of Thumb)

  • Rule 1: ASAN and TSAN are mutually exclusive. If both are enabled, ASAN is silently disabled.
    • Action: Use `THREADSAN=1 DISABLE_SANITIZER=1 make debug` for thread sanitizer.
    • Action: Use `make debug` (default) for address sanitizer.
  • Rule 2: UBSAN and TSAN are mutually exclusive. If both are enabled, UBSAN is silently disabled.
  • Rule 3: On Apple M1 (ARM64) with Clang < 14.0, the vptr sanitizer produces false positives.
    • Action: Set `DISABLE_VPTR_SANITIZER=1 make debug` to suppress.
    • Note: Clang >= 14.0 on M1 does not need this workaround (the bug was fixed).
  • Rule 4: Use `FORCE_SANITIZER=1` to enable sanitizers even in release builds for performance-aware testing.

Reasoning

ASAN and TSAN instrument memory differently and their runtime implementations conflict. The DuckDB build system prioritizes TSAN over ASAN when both are enabled, based on the logic that thread bugs are usually what you're specifically looking for when you enable TSAN.

Code evidence from `CMakeLists.txt:182-188`:

if(${ENABLE_THREAD_SANITIZER})
  if(${ENABLE_SANITIZER})
    message(
      WARNING
        "Both thread and address sanitizers are enabled. This is not supported.
         The address sanitizer will be disabled, and we will run with only the
         thread sanitizer.")
  endif()
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDUCKDB_THREAD_SANITIZER")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")

M1 vptr workaround from `CMakeLists.txt:199-210`:

if (NOT ${DISABLE_VPTR_SANITIZER})
  if(APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
    if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER 14.0)
      message(
        WARNING
          "Not disabling vptr sanitizer on M1 Macbook - set
           DISABLE_VPTR_SANITIZER manually if you run into issues
           with false positives in the sanitizer")
    else()
    set(DISABLE_VPTR_SANITIZER TRUE)
    endif()
  endif()
endif()

Makefile flags from `Makefile:43-57`:

ifeq (${DISABLE_SANITIZER}, 1)
	DISABLE_SANITIZER_FLAG=-DENABLE_SANITIZER=FALSE -DENABLE_UBSAN=0
endif
ifeq (${DISABLE_VPTR_SANITIZER}, 1)
	DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DDISABLE_VPTR_SANITIZER=1
endif
ifeq (${THREADSAN}, 1)
	DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DENABLE_THREAD_SANITIZER=1
endif

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment