Commit 61ba7ff
committed
gh-148286: Fix undefined behaviour in per-thread refcount merging (free-threaded)
_PyObject_MergePerThreadRefcounts() merges each thread's local reference
count deltas into the shared count:
_Py_atomic_add_ssize(&obj->ob_ref_shared,
refcnt << _Py_REF_SHARED_SHIFT);
`refcnt` is a delta, so it is routinely negative -- the observed value is
almost always -1 -- and shifting a negative value left is undefined
behaviour. Do the shift in the unsigned domain and convert back.
This is not reachable from the UBSan CI job today: the sanitizer matrix in
.github/workflows/build.yml pairs UBSan only with free-threading: false, so
this file is never built under UBSan. Building --disable-gil with
--with-undefined-behavior-sanitizer shows how load-bearing it is; the very
first line of output from `./python -c pass` is the UBSan report, raised
from interpreter startup via _PyImport_InitExternal, and it recurs from
gc_collect_main on every collection.
Measured over the full test suite on that configuration, with all entries
in Tools/ubsan/suppressions.txt disabled:
before: 1762 UB reports, 529 test failures across 61 test files
after: 0 UB reports, 0 failures, suite green (run=51,517)
Most of those failures are tests that assert a subprocess produced no
stderr, which the UBSan diagnostic breaks.
Adding free-threading: true to the UBSan matrix would keep this fixed; that
is left as a separate decision since it costs a CI job.1 parent f4b1d3e commit 61ba7ff
2 files changed
Lines changed: 10 additions & 1 deletion
File tree
- Misc/NEWS.d/next/Core and Builtins
- Python
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
184 | 187 | | |
185 | | - | |
| 188 | + | |
| 189 | + | |
186 | 190 | | |
187 | 191 | | |
188 | 192 | | |
| |||
0 commit comments