[Python-bugs-list] [Bug #110599] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)

noreply@sourceforge.net noreply@sourceforge.net
Wed, 23 Aug 2000 07:28:36 -0700


Bug #110599, was updated on 2000-Jul-31 21:05
Here is a current snapshot of the bug.

Project: Python
Category: Core
Status: Open
Resolution: None
Bug Group: None
Priority: 5
Summary: bug (Incorrect signal processing) - Python 1.5.2 (PR#102)

Details: Jitterbug-Id: 102
Submitted-By: "=?iso-8859-2?B?VmxhZGlt7XIgQmVuZbk=?=" <Vladimir.Benes@pvt.cz>
Date: Mon, 11 Oct 1999 13:00:07 +0200
Version: None
OS: None

Good afternoon,

    I have found a bug on Python 1.5.2. This bug doesn't occur on Python
1.5.1.

Python versions and OS:
- Python 1.5.1. at Debian GNU/Linux 2.0.36
- Python 1.5.2. at Debian GNU/Linux 2.2.9

Bug: Incorrect signal processing (Python 1.5.2).
    Process can assign procedure for signal processing. When process is
waiting at system call and this signal occur, then the signal assigned
procedure is otherwise correctly completed but then waiting at system call
is broken and process continues.

    Here is a simple program for demonstrate this bug:

#!/usr/bin/python
import signal
import sys

def signal_handle(signum, frame) :
  signal.signal(signal.SIGALRM, signal_handle)
  signal.alarm(2)
  print "signal"

signal_handle(0,0)
a=sys.stdin.readline()
print "Line examined..."
b=sys.stdin.readline()
print "Line examined..."
print a,b,"end"
# end of example

    Correct behaviour: Message "Line examined..." occurs only after pressing
ENTER by user.
    Bug: Message "Line examined..." occurs immediately after signal occured
and procedure signal_handle finished. Output then look thus (when no input
entered):

signal
signal
Line examined...
signal
Line examined...
  end

    This bug appears at any signal occur and whatever process waiting at
system call. Some system call even produces exception (e.g. waiting for data
or connection on socket).

    Bug is perhaps caused by wrong seting "siginterrupt" on module signal. I
haven't found any way how call in Python program "siginterrupt" for correct
behavior of signal processing.

        Good bye, V. Benes

****************************************************************************
    Ing. Vladimir Benes, pvt.net
    PVT, a.s., OZ Chomutov
    e-mail: vladimir.benes@pvt.cz, vladimir.benes@sms.paegas.cz
****************************************************************************



====================================================================
Audit trail:
Mon Oct 11 18:12:13 1999	guido	moved from incoming to open

Follow-Ups:

Date: 2000-Jul-31 21:05
By: none

Comment:
From: Jeremy Hylton <jeremy@cnri.reston.va.us>
Subject: Re: [Python-bugs-list] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)
Date: Tue, 12 Oct 1999 12:04:42 -0400 (EDT)

>>>>> "VB" == Vladimir Benes <Vladimir.Benes@pvt.cz> writes:

  VB> Bug: Incorrect signal processing (Python 1.5.2).  Process can
  VB> assign procedure for signal processing. When process is waiting
  VB> at system call and this signal occur, then the signal assigned
  VB> procedure is otherwise correctly completed but then waiting at
  VB> system call is broken and process continues.

[example program]

I see the behavior you report for 1.5.2 on Solaris 2.6.

  VB>     This bug appears at any signal occur and whatever process
  VB> waiting at system call. Some system call even produces exception
  VB> (e.g. waiting for data or connection on socket).

These issues always occur in twos don't they.  There was a similar
question posted on comp.lang.python yesterday.  I'm not sure that the
behavior you're seeing is a bug; it is the behavior I would expect.
Slow system calls are interrupted, returning EINTR, when a signal
occurs. 

  VB>     Bug is perhaps caused by wrong seting "siginterrupt" on
  VB> module signal. I haven't found any way how call in Python
  VB> program "siginterrupt" for correct behavior of signal
  VB> processing.

Perhaps the signal module for Python should be extended to support
siginterrupt, but it sounds like it will only reduce the number of
system calls that can be interrupted.  The Solaris man page says:

    NOTES
         Use of these interfaces should be restricted to only  appli-
         cations  written  on BSD platforms.  Use of these interfaces
         with any of the system libraries or in multi-threaded appli-
         cations is unsupported.

It doesn't sound particularly safe.

Jeremy

-------------------------------------------------------

Date: 2000-Jul-31 21:05
By: none

Comment:
From: "=?iso-8859-2?B?VmxhZGlt7XIgQmVuZbk=?=" <Vladimir.Benes@pvt.cz>
Subject: Re: [Python-bugs-list] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)
Date: Wed, 13 Oct 1999 09:19:44 +0200

From: Jeremy Hylton <jeremy@cnri.reston.va.us>
To: Vladimir.Benes@pvt.cz <Vladimir.Benes@pvt.cz>
Cc: python-bugs-list@python.org <python-bugs-list@python.org>;
bugs-py@python.org <bugs-py@python.org>
Date: 12. 10. 1999 18:04
Subject: Re: [Python-bugs-list] bug (Incorrect signal processing) - Python
1.5.2 (PR#102)


JH>I see the behavior you report for 1.5.2 on Solaris 2.6.


    You don't write whether this bug appeared there.

 JH> ......  I'm not sure that the
 JH> behavior you're seeing is a bug; it is the behavior I would expect.
 JH> Slow system calls are interrupted, returning EINTR, when a signal
 JH> occurs.


    I'am sure that this behavior is bug becouse:

1. I wrote the same program in C language (see below).
2. I ran this program at the same machine where the Python *)
    program works incorrectly.
3. Behavior of C program is correct (line scan is ended only when
    user press ENTER and this end is independed on signal).

=> The C program works correct and the same Python *) program fails at the
same platform. Base run of program should by independed on signal processing
except program terminating signals. It's independed at C program but
incorrect processed by Python *) programs.

*) only Python 1.5.2; Python 1.5.1 here works correctly

    Here is the mentioned program:

#include<stdio.h>
#include <unistd.h>
#include <signal.h>

void signal_handle(int signum) {
  signal(SIGALRM, signal_handle);
  alarm(2);
  printf("signal\n\r");
}

void main(void) {
  char a[100], b[100];

  signal_handle(0);
  scanf("%s",&a);
  printf("Line examined...\n\r");
  scanf("%s",&b);
  printf("Line examined...\n\r");
  printf("%s\t%s\tend\n\r", a, b);
}

 VB>     Bug is perhaps caused by wrong seting "siginterrupt" on
 VB> module signal. I haven't found any way how call in Python
 VB> program "siginterrupt" for correct behavior of signal
 VB> processing.


 JH> Perhaps the signal module for Python should be extended to support
 JH> siginterrupt, but it sounds like it will only reduce the number of
 JH> system calls that can be interrupted.  .......


    Sorry, I wrong formulated possible couse of bug. I will try to specify
my idea:
    It looks that there is any wrong calling "siginterupt" on signal module.
Python libraries doesn't allow me to try correct this bug by calling
"siginiterrupt" in my program before signal setting. But the best way is to
reapir bug on signal module.

    Good bye, V. Benes


-------------------------------------------------------

Date: 2000-Jul-31 21:05
By: none

Comment:
From: Guido van Rossum <guido@CNRI.Reston.VA.US>
Subject: Re: [Python-bugs-list] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)
Date: Wed, 13 Oct 1999 08:57:25 -0400

>  JH> ......  I'm not sure that the
>  JH> behavior you're seeing is a bug; it is the behavior I would expect.
>  JH> Slow system calls are interrupted, returning EINTR, when a signal
>  JH> occurs.
> 
[Vladimir]
>     I'am sure that this behavior is bug becouse:

When I first thought about this, I agreed with Vladimir.  If you look
careful at his code, readline() is returning "" when the alarm goes
off; this can't be right, because it's not an end of file.  It should
either raise an exception (EINTR) or return one line of valid data.

On the other hand, whatever solution is chosen should be careful that
other signals raise exceptions; in particular you want SIGINT (^C) to
be translated to a KeyboardError exception.  Since the C code in
readline() can't tell which signal was trapped or whether the handler
raised an exception, it has two choices, both of which are bad:

- Raise an IOError exception, honoring the EINTR.  Unfortunately, in
the SIGINT/^C case, the handler will run after this exception is
raised, and it will raise KeyboardError.  The Python program will
*probably* see the KeyboardError exception, but it is not guaranteed
that the signal handler is run immediately.  (The Python-level signal
handler is run only after the Python virtual machine finishes the
current instruction, i.e. after the readline() completes.)

- Continue to read a line, ignoring the EINTR.  Unfortunately, this
would mean that the user has to type ^C followed by Return to
interrupt the program!

An alternative solution would be to arrange for the Python-level
interrupt handler to execute inside the readline() method, and to
restart the read only when it raises no exception; but this would
require a massive code rewrite (you'd want this behavior in any place
that does a blocking I/O operation).

Concluding, I think Vladimir is better off not to use signal handlers
in the way he is using them now.  Python's emulation of signal
semantics is sufficiently different from C that you can't rely on the
same behavior.  (And note that in C, signal handlers are usually
broken anyway; e.g. the code you write, which prints something inside
the signal handler, is broken on C too because you don't know the
state of stdout when the handler is invoked.)

I looked at what could be different between 1.5.1 and 1.5.2, and found 
that the call to siginterrupt() to disable restarting system calls was 
added after 1.5.1.  Given the alternatives, I think I like the 1.5.2
behavior better than the 1.5.1 behavior.

--Guido van Rossum (home page: http://www.python.org/~guido/)

-------------------------------------------------------

Date: 2000-Jul-31 21:05
By: none

Comment:
From: "=?iso-8859-2?B?VmxhZGlt7XIgQmVuZbk=?=" <Vladimir.Benes@pvt.cz>
Subject: Re: [Python-bugs-list] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)
Date: Wed, 13 Oct 1999 16:34:39 +0200

>...
>Concluding, I think Vladimir is better off not to use signal handlers
>in the way he is using them now.  Python's emulation of signal
>semantics is sufficiently different from C that you can't rely on the
>same behavior.  (And note that in C, signal handlers are usually
>broken anyway; e.g. the code you write, which prints something inside
>the signal handler, is broken on C too because you don't know the
>state of stdout when the handler is invoked.)


    Well, meantioned programs were only very simple demos for demonstrate
incorrect signal processing. But exists a large range of meaningful programs
where is necessary both synchronous and asynchronous signal processing - and
signal can be triggered whenever.

    Example of C symbolic structure this programs:

....
int event_flag;
void trigger_signal(int signum) {
  // asynchonous signal processing
  event_flag = MY_EVENT; // only flag set
}
void initialize_signal(int sig) {
  event_flag = NO_EVENT; // initialize
  signal(sig, trigger_signal);
}
int main() {
  initialize_signal(SIGTERM);
  while (1) {
    my_func();
    // synchronous signal processing:
    if (event_flag==MY_EVENT) my_sync_trigger();
  }
}

    Signal can be raised whenever when function my_func runs => flag
event_flag is then set but my_func "does't know" his and continues at own
processing. Signal should not influence my_func becouse my_func "doesn't
know" both this signal and flag event_flag. Function event_flag can wait for
system call (read, write, connect, etc). Incoming signal should not finish
this waiting after trigger_signal function processing. So my_func is
independed on signal processing and "does'nt know" signals.

    Program tests the flag at any "safe" location(s). If this flag is set,
program run specific synchronous signal processing. It can be for example
safe program end or synchronous SIGALRM processing.

    Python programs can by compose similar this example.

>I looked at what could be different between 1.5.1 and 1.5.2, and found
>that the call to siginterrupt() to disable restarting system calls was
>added after 1.5.1.  Given the alternatives, I think I like the 1.5.2
>behavior better than the 1.5.1 behavior.


    But then old Python programs writen for Python 1.5.1 are not compatible
with Python 1.5.2. in this feature. I thing that better way is to let this
behavior equal as in Python 1.5.1. but allow programs to call either new
function "siginterrupt" at signal module (more flexible solution) or any
else new function at signal module to set behavior signal processing by Your
idea.

        Good bye, V. Benes


-------------------------------------------------------

Date: 2000-Aug-10 18:45
By: gvanrossum

Comment:
Sorry, I can't take this.  It's an issue though!  There are a bunch of signal related bugs in Linux...
-------------------------------------------------------

For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=110599&group_id=5470