[New-bugs-announce] [issue20584] On FreeBSD, signal.NSIG is smaller than biggest signal value

Jan-Philip Gehrcke report at bugs.python.org
Mon Feb 10 18:36:38 CET 2014

New submission from Jan-Philip Gehrcke:

On FreeBSD, signal.NSIG is smaller than what the documentation promises: "One more than the number of the highest signal number".

On Linux, the highest numerical signal value is smaller/equal signal.NSIG (expected behavior):

>>> import signal
>>> signals = [s for s in dir(signal) if s.startswith("SIG")]
>>> max([(getattr(signal, s), s) for s in signals])
(64, 'SIGRTMAX')
>>> signal.NSIG

On FreeBSD (since version 7, when SIGRTMIN/MAX have been introduced), Python's signal.NSIG is either 32 (if defined by the system, depending on __BSD_VISIBLE, see http://svnweb.freebsd.org/base/head/sys/sys/signal.h?revision=233519&view=markup#l331) or 64 (if chosen by signalmodule.c as a fallback). In any case, on FreeBSD the numerical values of SIGRTMIN/MAX are 65 and 126 and therefore both greater than Python's signal.NSIG:

Consequently, Python's signal module exposes a number NSIG which is not 'true'. Two disadvantages:

- signal.NSIG is just not meaningful on FreeBSD. It is part of the signal module's public interface, and should do what its documentation says: "One more than the number of the highest signal number".

- this might lead to unexpected behavior when for instance calling signal.signal(signal.SIGRTMAX, signal.SIG_DFL). This works on Linux, but fails with a ValueError on FreeBSD: raised directly by signalmodule.c, because sig_num >= NSIG, i.e. sig_num seemingly is an invalid signal number, although it is not (https://github.com/python/cpython/blob/3.3/Modules/signalmodule.c#L323). This is the reason why I became aware of this topic.

I see three arguments here:

- if the system does not provide NSIG via signal.h and Python's signalvalue makes the wrong guess (i.e. fallback to 64), then signalmodule.c would be to blame.

- if the system provides NSIG via signal.h and this is not the true maximum, then one could say that Python is not to blame.

- on the other hand, signalmodule.c is aware of all signals that it actively checked for and therefore could derive "One more than the number of the highest signal number" on its own via something in the lines of max(signal_values)+1.

Regarding the latter point: if Python misses to check for a valid signal on a certain platform, then this actively derived NSIG value would not be entirely correct, either, seen from the platform's perspective. But the signal module would then at least be consistent with itself.

In case of FreeBSD, I am actually not sure if signal.NSIG *is* provided by the system or determined by the fallback method in signalmodule.c (I can't get my hands on a FreeBSD machine at the moment).

What do you think?

Btw, parts of this have already been mentioned here: http://bugs.python.org/issue12060

components: Library (Lib)
messages: 210854
nosy: jgehrcke, neologix, sdaoden
priority: normal
severity: normal
status: open
title: On FreeBSD, signal.NSIG is smaller than biggest signal value
type: behavior
versions: Python 2.7, Python 3.1, Python 3.2, Python 3.3

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list