Closed
Description
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