[Python-bugs-list] [Bug #125673] PyThreadState_Delete: invalid tstate (Unix only?)
noreply@sourceforge.net
noreply@sourceforge.net
Sat, 20 Jan 2001 23:20:12 -0800
Bug #125673, was updated on 2000-Dec-13 08:25
Here is a current snapshot of the bug.
Project: Python
Category: Threads
Status: Open
Resolution: None
Bug Group: Platform-specific
Priority: 5
Submitted by: gvanrossum
Assigned to : gvanrossum
Summary: PyThreadState_Delete: invalid tstate (Unix only?)
Details: I am working on a simple couroutine/generator package using
threads,
to prototype the API. It seems to be working fine, except it is
exposing a hard-to-find bug in the threadstate code. The following
script[*] contains the API implementation and a simple example based on
Tim's "fringe()" code. When I run the example, I *sometimes* get:
Segmentation fault
but *sometimes* I get:
Fatal Python error: PyThreadState_Delete: invalid tstate
Aborted
and *sometimes* it succeeds. If I uncomment the raw_input("Exit?")
line at the end I never get an error. The error behavior seems very
fickle: making almost arbitrary changes to the code can trigger it or
make it go away. When I run it under gdb, I cannot reproduce the
problen, ever. (Haven't I heard this before?)
The only clue is the fatal error message: it seems to be a race
condition at thread termination. But how to debug this?
_____
[*] I'm not including the script here.
I can mail it to interested parties though. For my own reference:
Subject: [Pycabal] Mysterious thread bug
To: <cabal>
Date: Thu, 16 Nov 2000 16:21:12 -0500
Follow-Ups:
Date: 2001-Jan-20 23:20
By: tim_one
Comment:
Guido, since we just fixed *a* thread termination problem (premature
clearing of "initialized" in pythonrun.c), and I've never seen this fail on
Windows, reassigning to you to see whether-- however unlikely it may seem
--this problem has gone away by magic now.
-------------------------------------------------------
Date: 2000-Dec-13 08:51
By: tim_one
Comment:
I was never able to provoke a problem on Windows using Guido's script, so
changed Group to Platform-specific and added "(Linux only?)" to Summary.
Here's the script; assigned to Greg under the hope he can provoke a
problem:
import thread
class EarlyExit(Exception):
pass
class main_coroutine:
def __init__(self):
self.id = 0
self.caller = None
self.value = None
self.lock = thread.allocate_lock()
self.lock.acquire()
self.done = 0
def __call__(self, value=None):
cur = current()
assert cur is not self
self.caller = cur
self.value = value
self.lock.release()
cur.lock.acquire()
if self.done:
raise EarlyExit
return cur.value
all_coroutines = {thread.get_ident(): main_coroutine()}
def current():
return all_coroutines[thread.get_ident()]
def suspend(value=None):
cur = current()
caller = cur.caller
assert caller and caller is not cur
caller.value = value
caller.lock.release()
cur.lock.acquire()
return cur.value
nextid = 1
class coroutine(main_coroutine):
def __init__(self, func, *args):
global nextid
self.id = nextid
nextid = nextid + 1
self.caller = current()
boot = thread.allocate_lock()
boot.acquire()
thread.start_new_thread(self.run, (boot, func, args))
boot.acquire()
def run(self, boot, func, args):
me = thread.get_ident()
all_coroutines[me] = self
self.lock = thread.allocate_lock()
self.lock.acquire()
self.done = 0
boot.release()
self.lock.acquire()
if self.value:
print "Warning: initial value %s ignored" % `value`
try:
apply(func, args)
finally:
del all_coroutines[me]
self.done = 1
self.caller.lock.release()
def fringe(list):
tl = type(list)
for item in list:
if type(item) is tl:
fringe(item)
else:
suspend(item)
def printinorder(list):
c = coroutine(fringe, list)
try:
while 1:
print c(),
except EarlyExit:
pass
print
if __name__ == '__main__':
printinorder([1,2,3])
l = [1,2,[3,4,[5],6]]
printinorder(l)
#raw_input("Exit?")
-------------------------------------------------------
For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=125673&group_id=5470