Author vstinner
Recipients benjamin.peterson, exarkun, gregory.p.smith, loewis, marcin.bachry, pitrou, python-dev, schmichael, spiv, tseaver, vstinner
Date 2011-05-03.23:53:06
SpamBayes Score 2.22045e-16
Marked as misclassified No
Message-id <1304466779.14458.12.camel@marge>
In-reply-to <1304429371.15.0.366924973954.issue8407@psf.upfronthosting.co.za>
Content
> Since the commit c9207c6ce24a, test_signal fails on OpenIndiana:
> 
> http://www.python.org/dev/buildbot/all/builders/x86%20OpenIndiana%203.x/builds/1179
> ======================================================================
> ERROR: test_block_unlock (test.test_signal.PthreadSigmaskTests)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/export/home/buildbot/64bits/3.x.cea-indiana-amd64/build/Lib/test/test_signal.py", line 539, in test_block_unlock
>     self.assertEqual(set(old_mask) ^ set(blocked), {signum})
>   File "/export/home/buildbot/64bits/3.x.cea-indiana-amd64/build/Lib/test/test_signal.py", line 501, in handler
>     1/0
> ZeroDivisionError: division by zero

This is because a thread different than the main thread receives the
signal and calls the signal handler. Antoine found that "python -m
test_pydoc test_signal" is enough to reproduce the problem (on any OS,
or at least on Linux). test_pydoc loads a lot (all?) of Python modules
including _tkinter, and _tkinter (libtcl) creates a C thread which waits
events using select().

I see 3 solutions:

a) Use pthread_kill() to send the signal directly to the right thread
(the main thread)

b) Destroy _tkinter: Tcl_Finalize() exits the thread, but this function
is never called. _tkinter.c contains the following code:
#if 0
    /* This was not a good idea; through <Destroy> bindings,
       Tcl_Finalize() may invoke Python code but at that point the
       interpreter and thread state have already been destroyed! */
    Py_AtExit(Tcl_Finalize);
#endif

c) Skip the test if the _tkinter thread is present. Check if the
_tkinter module is loaded *should* be enough to check if the Tcl thread
is running. Unload the _tkinter module is not possible: modules written
in C cannot be unloaded. But it is possible to remove all references
from the Python object space, so check >'_tkinter' in sys.modules< is
maybe not reliable.

I don't know if some platforms have pthread_sigmask() but not
pthread_kill().

I have a patch to expose pthread_kill(), sigpending() and sigwait(). I
will publish it tomorrow for a review.

--

test_signal doesn't fail on all platforms. Possible reasons:

 - the platform doesn't have pthread_sigmask(), and so the test is
skipped
 - the libtcl version is different, a newer version masks maybe signals?
 - (unlikely!) os.kill() always sends the signal to the main thread
History
Date User Action Args
2011-05-03 23:53:08vstinnersetrecipients: + vstinner, loewis, gregory.p.smith, spiv, exarkun, tseaver, pitrou, benjamin.peterson, marcin.bachry, schmichael, python-dev
2011-05-03 23:53:06vstinnerlinkissue8407 messages
2011-05-03 23:53:06vstinnercreate