Data race in list.sort() on no-gil build
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
Summary
As reported in #153852 (TSAN0014), list.sort() writes each slot of the array with a plain, non-atomic store. When another thread concurrently accesses the same list, there is a data race between the in-place sort and the reader, which will be reported by TSAN.
How to reproduce
First we need to enable thread-sanitizer
- ./configure --disable-gil --with-thread-sanitizer
- TSAN_OPTIONS="halt_on_error=1 symbolize=1 history_size=4" ./python repro.py
Then run the following repro.py
import sys, threading
size, rounds, num_threads = 2000, 1500, 32
SCRAMBLED = sorted(range(size), key=lambda x: (x * 2654435761) & 0xFFFFFFFF)
global_list = list(SCRAMBLED)
enter, leave = threading.Barrier(num_threads + 1), threading.Barrier(num_threads + 1)
def reader():
for _ in range(rounds):
enter.wait()
for _x in global_list:
pass
leave.wait()
def main_sorter():
for _ in range(rounds):
global_list[:] = SCRAMBLED
enter.wait()
global_list.sort()
leave.wait()
ts = [threading.Thread(target=reader) for _ in range(num_threads)]
for t in ts:
t.start()
main_sorter()
for t in ts:
t.join()
Finally we could see the log from TSan
WARNING: ThreadSanitizer: data race (pid=3143552)
Write of size 8 at 0xffffb6b3c018 by main thread:
#0 binarysort Objects/listobject.c:1918 (python+0x1c64bc)
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-154572
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit der Ausführung von repro.py mit der aufgeführten no-GIL- und ThreadSanitizer-Konfiguration und untersuche anschließend Objects/listobject.c im Bereich von binarysort in Zeile 1918. Vergleiche den Race-Report mit der verlinkten Arbeit gh-154572. Als abgeschlossen gilt die Aufgabe, wenn die Reproduktion keinen ThreadSanitizer-Data-Race-Report mehr erzeugt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- c, python
- Bereich
- operating-systems, testing-qa
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 30/100