Skip to content

build: link test runners against a ReleaseSafe Zig library - #108

Merged
ata-sesli merged 1 commit into
mainfrom
build/zig-releasesafe-tests
Nov 3, 2026
Merged

ata-sesli merged 1 commit into
mainfrom
build/zig-releasesafe-tests

Conversation

@ata-sesli

Copy link
Copy Markdown
Member

Summary

Test builds now compile the Zig library (libcbm_zig.a) as ReleaseSafe. Before this change it was built ReleaseFast for tests as well as for releases. Release builds stay ReleaseFast.

Why

The test runners are built with AddressSanitizer and UBSan, but those sanitizers only instrument C code. In a ReleaseFast Zig build, Zig's own runtime checks are also off. So in the ported modules (git, simhash, watcher, discover and the CLI module), these errors were undefined behaviour that no test could detect:

  • an out-of-bounds index;
  • an integer overflow;
  • an @intCast that doesn't fit;
  • reaching unreachable.

ReleaseSafe keeps those checks. A violation becomes a panic with a stack trace pointing at the Zig line.

This matters more for the next migration step: cypher.c is about 6,000 lines of string and buffer code that the sanitizers check today. Once it's ported, these checks are the only thing that can catch the same class of bug in tests.

Changes

  • build.zig: addCbmZigLibrary now takes the build kind. It uses ReleaseSafe for .tests (the test-support library and every test runner) and ReleaseFast for .prod. CI's test runner is built through this path (scripts/zova-build-test-runner.sh).
  • Makefile.cbm:
    • translate-c now has its own cbm_c.zig rule, shared by two library rules: the existing ReleaseFast libcbm_zig.a and a new ReleaseSafe libcbm_zig_test.a;
    • test-runner and test-repro-runner link the test library;
    • with CBM_PREBUILT_ZIG=1, the test runners fall back to the release library. Prebuilt artifacts are used only by the Windows release build, which ships only the release library.

Verification

All on macOS arm64.

  • Full suite with CBM_TEST_TIERS=all (all language tiers): 6,447 passed, the same as main at ea95a61. No module panicked under the new checks.
  • The checks are live in tests: I temporarily added an out-of-bounds write to cbm_minhash_jaccard. The simhash suite then aborted with panic: index out of bounds: index 1, len 1 at that line, with a trace into test_minhash_renamed_vars_same_fingerprint. The probe was removed and is not in this PR.
  • Makefile path: both libraries build. nm shows 31 Zig panic-handler symbols in libcbm_zig_test.a and none in libcbm_zig.a.
  • Other checks: tests/test_github_workflows.sh, git diff --check and zig fmt --check build.zig all pass.

Not checked locally

  • The Linux CI runner, which this PR's CI covers.
  • A full ASan make test link through the Makefile. Only the two library targets were built that way.

The test runners are built with ASan and UBSan, but the sanitizers do not
instrument Zig code, and libcbm_zig.a was built ReleaseFast for tests too.
Out-of-bounds indexing, integer overflow and failed @intcast in the Zig
modules were therefore undefined behaviour that no test could catch.

Test builds now compile the Zig library ReleaseSafe, which keeps those
checks and turns a violation into a panic with a stack trace. Release
builds stay ReleaseFast.

- build.zig: addCbmZigLibrary takes the build kind and picks ReleaseSafe
  for .tests.
- Makefile.cbm: translate-c gets its own cbm_c.zig rule, shared by the
  release library and a new libcbm_zig_test.a that test-runner and
  test-repro-runner link. With CBM_PREBUILT_ZIG=1 (release-only
  artifacts) the test runners fall back to the release library.

Signed-off-by: ata-sesli <atasesli@protonmail.com>
@ata-sesli
ata-sesli merged commit 665f1d5 into main Nov 3, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant