python / python/cpython

Data race in list.sort() on no-gil build

Aberta
#154,756 0 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

interpreter-core topic-free-threading type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
35.9k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

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

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece executando repro.py com a configuração no-GIL e ThreadSanitizer listada e, em seguida, inspecione Objects/listobject.c em torno de binarysort na linha 1918. Compare o relatório de race com o trabalho vinculado gh-154572. A tarefa estará concluída quando a reprodução não produzir mais um relatório de data race do ThreadSanitizer.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
c, python
Domínio
operating-systems, testing-qa
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
30/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.