Skip to content

Attribution: harness copies, bare file names, PyO3 frames and thread names - #1

Merged
nimbrel merged 7 commits into
mainfrom
fix/attribution-harness-and-paths
Sep 26, 2026
Merged

nimbrel merged 7 commits into
mainfrom
fix/attribution-harness-and-paths

Conversation

@nimbrel

@nimbrel nimbrel commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

Fixes in how TSan reports are classified and located.

  • A mutator refilling another library's buffer (e.g. a numpy array via arr[:] = ...) goes through that library's copy loop, not CPython's, and was filed as the extension's certain race, failing the run. A copy primitive called from outside the interpreter, with no extension frame and no free/realloc/resize on the mutator's stack, is now a harness race, located at the extension's access.
  • A bare source file name in an uninstrumented library's debug info was resolved against the working directory (the crate root in the image) and became a finding's primary location. Non-absolute paths are no longer treated as crate files.
  • Races outside the extension are located at the plain access, not at an atomic helper from pyatomic*.h.
  • Messages name the racing threads, text stacks are labelled with them, and JSON stacks gain a thread field.
  • A race whose access is inside PyO3's own source says so, with the PyO3 version and line.

14 new tests in tests/test_tsan_parse.py with a synthetic data log; the TSan ground-truth suite passes locally (33 passed, 4 xfailed).

An uninstrumented library can record a source file with no directory. It
was resolved against the working directory, which is the crate root in the
image, so it passed for a crate file and became the primary location and
the merge key. Only an absolute path under the crate root now counts.

Signed-off-by: nimbrel <[email protected]>
…s race

Only CPython's own content writers were recognised. A mutator refilling a
numpy array reaches the buffer through numpy's copy loop and memmove, so the
report was filed as the extension's certain race and failed the run.

A mutator stack now counts as a content rewrite when a copy primitive is at
the top, called from a library outside the interpreter, with no frame of
the extension and no free, realloc or resize anywhere on it. CPython's
containers stay excluded: their copies run under a critical section the
extension must also hold. Harness races are located at the extension's
access rather than in the mutator's library.

Signed-off-by: nimbrel <[email protected]>
When one side of a report not attributed to the extension was an atomic
helper from CPython's pyatomic headers, that side could become the primary
location. The plain access is the racy one, so it is preferred.

Signed-off-by: nimbrel <[email protected]>
A race whose access happened in PyO3's own source was reported at the
extension's frame with no mention of PyO3. The classification and location
are unchanged; the message now names the PyO3 crate, version and line, since
a newer PyO3 may have changed that access.

Signed-off-by: nimbrel <[email protected]>
Messages said "by thread T7", so a report caused by a mutator could not be
recognised without the raw log. The thread's name now follows its id in the
message, each stack carries a "thread" field in the JSON, and the text
summary labels stacks with it. Deduplication is unaffected: the signature
does not include the message.

Signed-off-by: nimbrel <[email protected]>
@nimbrel
nimbrel merged commit 516475b into main Sep 26, 2026
6 checks passed
nimbrel added a commit that referenced this pull request Sep 26, 2026
… frames and thread names

TSan reports from a mutator refilling another library's buffer are classified as harness races, bare debug-info file names are no longer taken for crate files, races outside the extension are located at the plain access, and messages name threads and PyO3 frames.
@nimbrel nimbrel mentioned this pull request Sep 27, 2026
@nimbrel
nimbrel deleted the fix/attribution-harness-and-paths branch September 28, 2026 12:44
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