tursodatabase/turso · error · SystemExit

{path} is missing dynsym exports: {', '.join(missing)}

Error message

{path} is missing dynsym exports: {', '.join(missing)}

What it means

This is the script's actual failure output: the ELF file was parsed successfully but one or more required symbols are absent from its .dynsym (dynamic symbol) table, meaning the shared library does not export them for dynamic linking. The script raises SystemExit listing all missing symbols. It exists to catch broken native builds early in CI.

Source

Thrown at bindings/dotnet/scripts/check_elf_dynsym_exports.py:26

TYPE = 1
OFFSET = 4
SIZE = 5
LINK = 6
ENTRY_SIZE = 9


def main() -> None:
    if len(sys.argv) == 2 and sys.argv[1] == "--self-test":
        run_self_test()
        return
    if len(sys.argv) < 3:
        raise SystemExit("usage: check_elf_dynsym_exports.py <elf> <symbol>...")

    path = Path(sys.argv[1])
    needed = sys.argv[2:]
    missing = missing_exports(path, needed)
    if missing:
        raise SystemExit(f"{path} is missing dynsym exports: {', '.join(missing)}")


def run_self_test() -> None:
    import tempfile

    symbol = "turso_sync_database_new"
    with tempfile.NamedTemporaryFile(delete=False, suffix=".so") as handle:
        handle.write(elf64_with_dynsym(symbol))
        path = Path(handle.name)
    try:
        if missing_exports(path, [symbol]):
            raise SystemExit("self-test failed: expected export was not found")
        if not missing_exports(path, ["turso_sync_database_missing"]):
            raise SystemExit("self-test failed: missing export was not reported")
    finally:
        path.unlink()

View on GitHub (pinned to 492c4a71cd)

Solutions

  1. Rebuild the native library with the symbol exported (check visibility attributes, #[no_mangle]/exports, and linker version scripts)
  2. Verify the symbol exists with `nm -D <elf> | grep <symbol>` to confirm before blaming the checker
  3. If the symbol was intentionally removed, update the required symbol list in the calling build/CI configuration
  4. Ensure the correct (unstripped, fully built) artifact path is passed, not a stub or cached intermediate

Example fix

// before (Cargo.toml / build.rs)
// symbol not exported
crate-type = ["cdylib"]
// missing #[no_mangle] pub extern "C"
// after
#[no_mangle]
pub extern "C" fn turso_sync_database_new() -> *mut Database { ... }
Defensive patterns

Strategy: validation

Validate before calling

import subprocess
out = subprocess.run(["nm", "-D", elf_path], capture_output=True, text=True)
missing = [s for s in required_symbols if s not in out.stdout]
assert not missing, f"missing exports: {missing}"

Try / catch

try:
    subprocess.run(["check_elf_dynsym_exports.py", elf, *symbols], check=True)
except subprocess.CalledProcessError:
    # inspect nm -D output, rebuild or fix export list
    ...

Prevention

When it happens

Trigger: Running `check_elf_dynsym_exports.py <elf> <symbol>...` where one of the listed symbols is not found in the ELF's .dynsym section; missing_exports() returns a non-empty list.

Common situations: A native library build dropped visibility flags (-fvisibility=hidden without exports), a linker version script stopped exporting the symbol, an API was renamed or removed in a dependency, or a stripped/incorrect artifact was shipped.

Related errors


AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-09-13). Data as JSON: /api/errors/3df2f9e012736da5. Report an issue: GitHub.