Skip to content

nogil set clear causes concurrent __str__ to print as empty dict #129967

Closed
@luisggpina

Description

@luisggpina

Bug report

Bug description:

Hi,

We're a research group focused on testing concurrent runtimes. Our work-in-progress prototype found that the current nogil build __str__ can return "{}" (empty dict) instead of the expected "set()" when there is a concurrent clear() operation. The program below shows the wrong behavior:

import threading
import sys
def t0(b1,s,res):
    b1.wait()
    s.clear()

def t1(b1,s,res):
    b1.wait()
    res.append(s.__str__())

def Test():
  s =  {17, 18, 'a', 'b', 'c', 'd', 'e'}
  threads=[]
  barrier = threading.Barrier(2)
  res = []
  threads.append(threading.Thread(target= t0, args=(barrier, s,res)))
  threads.append(threading.Thread(target= t1, args=(barrier, s,res)))
  for i in range(0, len(threads)):
      threads[i].start()
  for i in range(0, len(threads)):
      threads[i].join()
  if res[0] == "{}":
      print("found bug: " + res[0])

print("test begin...")
for i in range(0,50000):
  threads = []
  if i % 1000 == 0:
      print(i)
  for i in range(0,100):
      threads.append(threading.Thread(target= Test))
  for t in threads:
      t.start()
  for t in threads:
      t.join()
print("test Done")

Sample output:

test begin...
0
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}
found bug: {}

This behavior can be observed quite readily. We tested it on a number of x86_64 and one ARM machine.

@flypoodles and @overlorde are part of the team, adding them so they get notified about further discussion.

CPython versions tested on:

3.14, CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions