Skip to content

tsan: foundation for multi-race-per-session (--tsan-no-halt + parse_all_reports) - #221

Merged
devdanzin merged 1 commit into
mainfrom
tsan-multi-race-foundation
Jul 19, 2026
Merged

tsan: foundation for multi-race-per-session (--tsan-no-halt + parse_all_reports)#221
devdanzin merged 1 commit into
mainfrom
tsan-multi-race-foundation

Conversation

@devdanzin

Copy link
Copy Markdown
Owner

Multi-race-per-session, part 1 of 4 (the enabling pieces)

Under halt_on_error=1 a --tsan session reports only its first race, so distinct races in the same session are masked. An experiment on one real _decimal fleet session confirmed the payoff: 10 distinct races surface when we don't halt (vs 1 halted) — including independent _decimal Context races that were hidden behind the count residual, plus a cascade SEGV.

This PR lands the two foundation pieces; the keep-policy sidecar (#3) and the ingest side (#4) follow in separate PRs.

#1 — emit (__init__.py)

--tsan-no-halt sets TSAN_OPTIONS halt_on_error=0 (report-and-continue). Opt-in; default stays 1. Detection is textual so races still score, and exit stays 66 (TSan's exitcode fires at exit when any error was reported — verified in the experiment).

#2 — parse (tsan_dedup.py)

parse_all_reports(text, source_roots=None) splits the stdout on TSan report-start headers (WARNING/ERROR, deliberately not SUMMARY) and parses each chunk, returning the distinct races in stream order with an order index — so a caller can flag reports that follow a UAF/SEGV as possible corruption artifacts (the first race is the trustworthy one). parse_report is unchanged (first-report only), so the sibling catalog's signature contract is untouched — purely additive.

Verified on the real 13-block experiment log: parse_all_reports returns 10 distinct races (count residual + its UAF faces + the _decimal Context races + a segv at order=9) where parse_report returns 1.

Tests

+4 (multiple distinct races, dedup-by-signature, single/empty, parse_report-still-first-only); suite 1131 → 1135; ruff clean.

🤖 Generated with Claude Code

…ll_reports)

Under halt_on_error=1 a session reports only its FIRST race, so distinct races in
the same session are masked (an experiment on one _decimal session showed 10
distinct races surface when not halted, incl. _decimal Context races masked
behind the count residual). This lands the two enabling pieces; the keep-policy
sidecar (#3) and ingest side (#4) follow.

#1 emit (__init__.py): --tsan-no-halt sets TSAN_OPTIONS halt_on_error=0
(report-and-continue). Opt-in; default stays 1. Detection is textual so races
still score, and exit stays 66 (TSan's exitcode fires at exit if any error was
reported).

#2 parse (tsan_dedup.py): parse_all_reports(text, source_roots=None) splits the
stdout on TSan report-start headers (WARNING/ERROR, not SUMMARY) and parses each
chunk, returning the distinct races in stream order with an `order` index (so a
caller can flag reports that FOLLOW a UAF/SEGV as possible corruption artifacts --
the first race is the trustworthy one). parse_report is UNCHANGED (first-report
only), so the sibling catalog's signature contract is untouched -- purely
additive. Verified on the real 13-block experiment log: 10 distinct races vs 1.

+4 tests (multiple distinct races, dedup-by-signature, single/empty,
parse_report-still-first-only); suite 1131 -> 1135. ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@devdanzin
devdanzin merged commit f585e61 into main Jul 19, 2026
2 checks passed
@devdanzin
devdanzin deleted the tsan-multi-race-foundation branch July 19, 2026 00:24
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