Skip to content

Architecture

Overview

abicheck is a Python CLI tool that compares two versions of a C/C++ shared library to detect ABI and API incompatibilities. Its core design idea is to reason over five independent sources of information about a library — the binary, its debug symbols, its public headers, its build-system data, and (optionally) its sources — instead of relying on a single data source. Each source is an additive evidence layer (L0–L4); feeding more layers both finds breaks the weaker layers are blind to and suppresses false positives they would raise. See Evidence layers: the five sources below for the model, and Evidence & Detectability for the conceptual companion.

abicheck supports Linux (ELF), Windows (PE/COFF), and macOS (Mach-O), each with implemented binary-metadata and header-AST support; debug-info cross-check is implemented for ELF (DWARF/BTF/CTF) and PE (PDB) but not for Mach-O — see the platform support matrix for the per-platform tool/format breakdown and per-toolchain CI-validation maturity (implemented capability and CI-proven maturity are not the same thing, especially on Windows).


Analysis pipeline

The CLI dumps each input into a normalized snapshot, enriches it with header AST and debug-info layers, then diffs the two snapshots to produce a verdict:

flowchart TD
    CLI["abicheck CLI<br/>(dump · compare)"]
    FMT{"Format detection<br/>(ELF / PE / Mach-O)"}
    ELF["ELF<br/>pyelftools"]
    PE["PE/COFF<br/>pefile"]
    MACHO["Mach-O<br/>macholib"]
    SNAP["L0 — Binary metadata<br/>Snapshot (JSON model)"]
    AST["L2 — Header AST<br/>castxml (all platforms)"]
    DBG["L1 — Debug-info cross-check<br/>DWARF/BTF/CTF (Linux) · PDB (Windows) · none on Mach-O"]
    CHK["Checker → Changes → Verdict"]

    CLI --> FMT
    FMT --> ELF
    FMT --> PE
    FMT --> MACHO
    ELF --> SNAP
    PE --> SNAP
    MACHO --> SNAP
    SNAP --> AST
    AST --> DBG
    DBG --> CHK

The analysis layers are independent and additive — each catches changes the others miss, and the checker reconciles them into a single verdict. The artifact layers (L0/L1/L2) are described in detail below; the build/source layers (L3/L4, plus the optional L5 reachability graph) are covered in Build & Source Packs.


Evidence layers: the five sources

abicheck's accuracy comes from treating compatibility analysis as a question of evidence: the more independent sources of information you give it about a library (binary, debug symbols, headers, build data, sources — abicheck additionally derives a sixth, the L5 reachability graph), the more it can prove and the fewer false positives it raises. Artifact-backed L0/L1/L2 evidence is authoritative for the shipped-ABI verdict; build/source L3/L4/L5 evidence may explain, localize, or add confidence to a finding, but never silently deletes an artifact-proven break (the authority rule). See Evidence & Detectability for the full model (all six layers, the --depth dial, and worked examples).


Artifact layers in detail

Each layer is read by a format-specific parser and contributes one kind of evidence; the exact per-platform reach of each is owned by the reference pages linked in the table, not restated here.

Layer What it reads Where it is documented in full
L0 binary metadata The export table, SONAME or install name, dependencies, symbol binding and versioning — ELF, PE/COFF and Mach-O each through their own parser Platform Support
L1 debug information Struct/class layout, member offsets, vtable slots and calling conventions from DWARF (with BTF and CTF as fallbacks on ELF) or PDB; separate debug files are found through a resolver chain (--debug-info, or a .abicheck.yml debug.debuginfod: true) Platform Support, Dump & Compare Flags
L2 header AST Declarations, signatures, enums, typedefs, access and noexcept from the public headers through castxml or clang (--ast-frontend); castxml emulates the external compiler's defines and include paths, and the clang backend is syntactic, so DWARF stays the layout authority on a clang-only host Header Backend Capabilities, Platform Support § Windows toolchains
L3 build context, L4 source replay Post-build, opt-in, never authoritative on their own: the ABI-relevant flags and toolchain from the build graph, and the macros, default arguments, constexpr values and uninstantiated templates only the sources carry — collected into a content-addressed build/source pack Build & Source Packs

Per the authority rule, every L3/L4 finding defaults to API_BREAK or risk and carries an explicit evidence-tier boundary so it is never read as a proven shipped-ABI break.


Key modules

For the module-by-module map — every source file grouped by area (data model, input resolution, binary/debug metadata, core diffing, policy, post-processing, workflows, reporting, compatibility) — see the Codebase Overview, which is the contributor-facing source of truth for the package layout.


Policy model

Policies control how detected changes are classified (BREAKING, API_BREAK, COMPATIBLE).

Built-in profiles:

Profile Behavior
strict_abi (default) Every ABI change at maximum severity
sdk_vendor Source-only changes downgraded to COMPATIBLE
plugin_abi Calling-convention changes downgraded to COMPATIBLE

Custom policies: YAML files with per-kind break|warn|ignore overrides.

Source of truth: BREAKING_KINDS, API_BREAK_KINDS, COMPATIBLE_KINDS, and RISK_KINDS sets in checker_policy.py.


Verdict system

The checker's five verdicts (NO_CHANGE, COMPATIBLE, COMPATIBLE_WITH_RISK, API_BREAK, BREAKING) and the exit code each maps to are owned by Verdicts and Exit Codes; this page does not restate the table.


Error model

Public exceptions are defined in abicheck/errors.py. Tool errors produce exit code 1.


Ladder: ← Limitations & Known Boundaries · Concepts c3 · Internals · Source & Build Data →