This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PyOS_FiniInterupts leaves signal.getsignal segfaulty
Type: crash Stage: resolved
Components: Interpreter Core Versions: Python 3.3, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: ferringb, pitrou, python-dev, vstinner
Priority: normal Keywords:

Created on 2012-03-02 10:41 by ferringb, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
test.py ferringb, 2012-03-02 10:41
sig.py pitrou, 2012-03-02 15:23
Messages (4)
msg154758 - (view) Author: Ferringb (ferringb) * Date: 2012-03-02 10:41
During Py_Finalize (pythonrun.c), it does the following:
1) suppress signal handling PyOs_FiniInterupts
2) clear caches
3) force gc collection; first for objects, then via wiping modules.

The problem is that for unix OSs, Modules/signal.c's PyOs_FiniInterrupts leaves itself in a state where its internal Handlers are effectively reset to NULL, except the various functions don't properly handle that scenario.

Attached is a test case demonstrating it; it segfaults on every python version I've tested (2.4->3.2; haven't tried 3.3).

Since this *only* occurs during the final gc sweep when modules are destroyed, its a bit of a pain in the ass to detect that we're in that scenario, and that we must not touch signal.getsignal lest it segfault the interp.  That said,

def _SignalModuleUsable():
try:
  signal.signal(signal.SIGUSR1, signal.signal(signal.SIGUSR1, some_handler))
  return True
except (TypeError, AttributeError, SystemError):
  # we were invoked in a module cleanup context.
  return False

does manage to poke the api just right so that it can be detected w/out segfaulting the interp.

Finally, note that while folks could point at __del__... its not really at fault.  Doing a proper weakref.ref finalizer can trigger the same- the fault is signal.c's PyOs_FiniInterrupts leaving the signal module in a bad state.  For the testcase, I used __del__ just because it was quicker/less code to do so.
msg154768 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-03-02 15:23
I needed to modify the script to make it crash under 3.2/3.3. Attaching modified version.

Here is the relevant part of the gdb traceback:

Program received signal SIGSEGV, Segmentation fault.
0x000000000052b87b in signal_getsignal (self=<module at remote 0x7ffff7f43a38>, args=(1,))
    at ./Modules/signalmodule.c:372
372	    Py_INCREF(old_handler);
Missing debug package(s), you should install: glibc-debug-2.12.1-11.3.mga1.x86_64
(gdb) bt
#0  0x000000000052b87b in signal_getsignal (self=<module at remote 0x7ffff7f43a38>, args=(1,))
    at ./Modules/signalmodule.c:372
#1  0x00000000005f520b in PyCFunction_Call (func=
    <built-in method getsignal of module object at remote 0x7ffff7f43a38>, arg=(1,), kw=0x0)
    at Objects/methodobject.c:81
msg188407 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-05-04 21:21
New changeset 0201d8fa8bd0 by Antoine Pitrou in branch '2.7':
Issue #14173: Avoid crashing when reading a signal handler during interpreter shutdown.
http://hg.python.org/cpython/rev/0201d8fa8bd0

New changeset 0dfd5c7d953d by Antoine Pitrou in branch '3.3':
Issue #14173: Avoid crashing when reading a signal handler during interpreter shutdown.
http://hg.python.org/cpython/rev/0dfd5c7d953d

New changeset 753bcce45854 by Antoine Pitrou in branch 'default':
Issue #14173: Avoid crashing when reading a signal handler during interpreter shutdown.
http://hg.python.org/cpython/rev/753bcce45854
msg188408 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-05-04 21:22
This should be fixed now. Thank you for diagnosing this bug!
History
Date User Action Args
2022-04-11 14:57:27adminsetgithub: 58381
2013-05-04 21:22:15pitrousetstatus: open -> closed
versions: + Python 3.4, - Python 3.2
messages: + msg188408

resolution: fixed
stage: resolved
2013-05-04 21:21:20python-devsetnosy: + python-dev
messages: + msg188407
2012-03-02 15:23:34pitrousetfiles: + sig.py
versions: + Python 3.3, - Python 2.6, Python 3.1
nosy: + vstinner, pitrou

messages: + msg154768
2012-03-02 10:41:33ferringbcreate