Issue 1215: documentation doesn't say that you can't handle C segfaults from python (original) (raw)

process

Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: BreamoreBoy, Rhamphoryncus, belopolsky, docs@python, eric.araujo, georg.brandl, gvanrossum, poolie, python-dev, schmir, tebeka, terry.reedy, vstinner
Priority: normal Keywords: easy, patch

Created on 2007-09-27 17:05 by tebeka, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
20110822-1525-signal-doc.diff poolie,2011-08-22 05:27 review
Messages (21)
msg56169 - (view) Author: Miki Tebeka (tebeka) * Date: 2007-09-27 17:05
The following code hangs Python: #!/usr/bin/env python import segfault import signal from os import _exit from sys import stdout def handler(signal, stackframe): print "OUCH" stdout.flush() _exit(1) if __name__ == "__main__": from sys import argv signal.signal(signal.SIGSEGV, handler) segfault.segfault() segfault is the following C module: #include <Python.h> static PyObject * segfault(PyObject *self, PyObject *args) { char *c; c = 0; *c = 'a'; return Py_BuildValue(""); } static PyMethodDef Methods[] = { { "segfault", segfault, METH_VARARGS, "will segfault"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; PyMODINIT_FUNC initsegfault(void) { Py_InitModule("segfault", Methods); }
msg56192 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-09-28 18:31
Why is this a Python bug?
msg56194 - (view) Author: Miki Tebeka (tebeka) * Date: 2007-09-28 19:59
Because it hangs Python :) I know, "while 1: pass" also hangs Python, however it'll nice if this behaviour was documented or (IMO better) that Python will raise an InvalidArgument exception on SIGSEGV (like it does for SIGKILL).
msg59842 - (view) Author: Ralf Schmitt (schmir) Date: 2008-01-12 22:25
If you replace your call segfault.segfault() with os.kill(os.getpid(), signal.SIGSEGV) everything works as expected. The problem is that the signal is just caught in the c handler (and a flag is set) and then the program continues with the offending *c = 'a'; statement, which again ends with a SIGSEGV and the handler being called. The documentation explicitly states "Because the C signal handler always returns, it makes little sense to catch synchronous errors like SIGFPE or SIGSEGV." I think raising that InvalidArgument exception is most probably the right thing to do (or at least printing a warning). Those that really want to handle SIGSEGV should do it from C anyway.
msg59844 - (view) Author: Adam Olsen (Rhamphoryncus) Date: 2008-01-12 23:20
The warning in the documentation should be strengthened. Python simply does not and cannot support synchronously-generated signals. It is possible to send a normally synchronous signal asynchronously, such as the os.kill() Ralf mentioned, so it's theoretically possible to use custom handlers for them. However, I can't think of any real use cases, and having such a handler would be asking for trouble if a real synchronously-generated signal was produced. I guess that's an argument for not allowing custom handlers. ;) Suggested documentation: "Because of the precarious nature of how synchronously-generated signals must be handled, the signal module does not allow installing handlers for them. This includes SIGSEGV, SIGFPE, SIGBUS, SIGILL, SIGABRT..." I haven't been able to find a canonical list if synchronously-generated signals. Furthermore, I've seen conflicting claims about SIGABRT.
msg59908 - (view) Author: Ralf Schmitt (schmir) Date: 2008-01-14 19:10
Should I work on a patch, which makes signal.signal raise an Exception for SIGSEGV, SIGBUS, SIGFPE,...?
msg59910 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-14 19:13
I'm not sure what the point of that would be. Somebody might want to send these asynchronously (using kill) which we might legitimately want to catch. Also you don't know which other synchronous signals a platform might define. I think at best a doc update on the relative uselessness of handlers for synchronous signals (with examples) is all we need.
msg59912 - (view) Author: Ralf Schmitt (schmir) Date: 2008-01-14 19:30
Those who want to legitimately catch SIGSEGV will end up with an uninterruptible python process using 100 % CPU on a real segmentation fault. But, then I can live with the current behaviour.
msg59913 - (view) Author: Adam Olsen (Rhamphoryncus) Date: 2008-01-14 19:32
In essence, it's a weakness of the POSIX API that it doesn't distinguish synchronous from asynchronous signals. The consequences of either approach seem minor though. I cannot imagine a sane use case for catching SIGSEGV, but documentation changes should be sufficient anyway. Suggested wording, if you take the documentation-only approach: "Because of the precarious nature of how synchronously-generated signals must be handled, it is impossible to handle them correctly from python. You should never install handlers for synchronously-generated signals, such as SIGSEGV and SIGFPE."
msg76995 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2008-12-05 09:42
The docs already say "Because the C signal handler always returns, it makes little sense to catch synchronous errors like :const:`SIGFPE` or :const:`SIGSEGV`." Should this still be reworded or promoted to a warning?
msg77045 - (view) Author: Adam Olsen (Rhamphoryncus) Date: 2008-12-05 17:51
I'm in favour of just the doc change now. It's less work and we don't really need to disable that usage.
msg107988 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-06-17 02:27
From the comments, it seems like this should be changed to a doc issue. Given that I do not know a 'synchronous' from an 'asynchronous' signal, I would want an expanded list if I were using this module. Strengthening 'little sense' to 'do not do it' makes sense, at least for 2.7 and 3.2.
msg116778 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-09-18 13:50
There are several suggestions inline as how how the docs should be changed.
msg127681 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-02-01 04:27
The consensus is that this is not a crash (and not even a bug). I am not sure what is the proper type for doc enhancement, but is certainly should not show up in a search for crashers.
msg142670 - (view) Author: Martin Pool (poolie) Date: 2011-08-22 05:11
The documentation for this can now point to the faulthandler module (in Python 3).
msg142675 - (view) Author: Martin Pool (poolie) Date: 2011-08-22 05:27
This patch tries to improve the documentation a bit more to address the issue that confused tebeka and to advertise faulthandler. Could someone review or apply it?
msg143236 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-08-30 21:56
> def handler(signal, stackframe): > print "OUCH" > stdout.flush() > _exit(1) What do you want to do on a SIGSEGV? On a real fault, you cannot rely on Python internal state, you cannot use any Python object. To handle a real SIGSEGV fault, you have to implement a signal handler using only *signal safe* functions.... in C. See faulthandler_fatal_error() function: https://github.com/haypo/faulthandler/blob/master/faulthandler.c#L257 > The documentation for this can now point to the faulthandler module > (in Python 3). For your information, faulthandler is available for Python older than 3.3 as a third party module: http://pypi.python.org/pypi/faulthandler > segfault is the following C module: For tests, you can use ctypes.string_at(0) to read a word from NULL. -- faulthandler installs a signal handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals: http://docs.python.org/dev/library/faulthandler.html
msg143244 - (view) Author: Martin Pool (poolie) Date: 2011-08-31 00:52
On 31 August 2011 07:56, STINNER Victor <report@bugs.python.org> wrote: > > STINNER Victor <victor.stinner@haypocalc.com> added the comment: > >> def handler(signal, stackframe): >>     print "OUCH" >>     stdout.flush() >>     _exit(1) > > What do you want to do on a SIGSEGV? On a real fault, you cannot rely on  Python internal state, you cannot use any Python object. To handle a real SIGSEGV fault, you have to implement a signal handler using only *signal safe* functions.... in C. Well, strictly speaking, it is very hard or impossible to write C code that's guaranteed to be safe after an unexpected segv too; who knows what might have caused it.  The odds are probably better that it will work in in C than in Python.  At any rate I think it's agreed that the original code is not supported and it's just the docs that need to change. So what do you think of <http://bugs.python.org/file22989/20110822-1525-signal-doc.diff> ?
msg143253 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-08-31 12:02
Le mercredi 31 août 2011 02:52:01, vous avez écrit : > > What do you want to do on a SIGSEGV? On a real fault, you cannot rely on > > Python internal state, you cannot use any Python object. To handle a > > real SIGSEGV fault, you have to implement a signal handler using only > > *signal safe* functions.... in C. > > Well, strictly speaking, it is very hard or impossible to write C code > that's guaranteed to be safe after an unexpected segv too It is possible if you only use signal safe functions. I think that no Python function is signal safe :-)
msg199111 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2013-10-06 19:21
I see not much to be done here, except from committing Martin's patch updated to the current trunk.
msg199112 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-10-06 19:22
New changeset b4444d16e333 by Georg Brandl in branch '3.3': Closes #1215: document better why it is not a good idea to catch e.g. SIGSEGV and refer to faulthandler. http://hg.python.org/cpython/rev/b4444d16e333
History
Date User Action Args
2022-04-11 14:56:27 admin set github: 45556
2013-10-06 19:22:43 python-dev set status: open -> closednosy: + python-devmessages: + resolution: fixedstage: resolved
2013-10-06 19:21:21 georg.brandl set messages: +
2011-08-31 12:02:31 vstinner set messages: +
2011-08-31 00:52:00 poolie set messages: +
2011-08-30 21:56:02 vstinner set messages: +
2011-08-30 16:05:28 eric.araujo set nosy: + vstinner, eric.araujoversions: + Python 3.3, - Python 2.6, Python 3.1, Python 2.7, Python 3.2
2011-08-22 05:27:06 poolie set files: + 20110822-1525-signal-doc.diffkeywords: + patchmessages: +
2011-08-22 05:15:01 poolie set title: Python hang when catching a segfault -> documentation doesn't say that you can't handle C segfaults from python
2011-08-22 05:11:14 poolie set nosy: + pooliemessages: +
2011-02-01 04:27:04 belopolsky set nosy: + belopolskymessages: + components: - Interpreter Coretype: crash ->
2010-09-18 13:50:35 BreamoreBoy set assignee: docs@pythonmessages: + nosy: + docs@python, BreamoreBoy
2010-06-17 02:27:19 terry.reedy set nosy: + terry.reedymessages: + versions: + Python 2.6, Python 3.1, Python 2.7, Python 3.2, - Python 2.5
2008-12-05 17:51:37 Rhamphoryncus set messages: +
2008-12-05 09:42:13 georg.brandl set nosy: + georg.brandlmessages: +
2008-01-20 20:05:19 christian.heimes set priority: normalkeywords: + easycomponents: + Documentation
2008-01-14 19:32:45 Rhamphoryncus set messages: +
2008-01-14 19:30:52 schmir set messages: +
2008-01-14 19:13:08 gvanrossum set messages: +
2008-01-14 19:10:04 schmir set messages: +
2008-01-12 23:20:23 Rhamphoryncus set nosy: + Rhamphoryncusmessages: +
2008-01-12 22:25:37 schmir set nosy: + schmirmessages: +
2007-09-28 19:59:03 tebeka set messages: +
2007-09-28 18:31:17 gvanrossum set nosy: + gvanrossummessages: +
2007-09-27 17:05:24 tebeka create