GNU bug report logs - #13018
fport_fill_input should handle EINTR

Previous Next

Package: guile;

Reported by: Aidan Gauland <aidalgol <at> no8wireless.co.nz>

Date: Wed, 28 Nov 2012 08:22:01 UTC

Severity: normal

Done: Mark H Weaver <mhw <at> netris.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 13018 in the body.
You can then email your comments to 13018 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Wed, 28 Nov 2012 08:22:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Aidan Gauland <aidalgol <at> no8wireless.co.nz>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Wed, 28 Nov 2012 08:22:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Aidan Gauland <aidalgol <at> no8wireless.co.nz>
To: bug-guile <at> gnu.org
Subject: fport_fill_input should handle EINTR
Date: Wed, 28 Nov 2012 21:19:06 +1300
Guile version: 3.2.0-4-amd64
OS: Debian wheezy GNU/Linux, kernel 3.2.0-4-amd64

In a program that maintains a TCP connection with a polling loop, I have
defined a signal handler with the `sigaction' procedure to terminate the
connection gracefully.  When the trapped signal is received (in this
case SIGINT) and the handler called, the following error message is
printed (full backtrace omitted):

ERROR: In procedure %read-line:
ERROR: In procedure fport_fill_input: Interrupted system call

I mentioned this on #guile on freenode and mark_weaver informed me that
I should be setting the SA_RESTART flag to avoid this problem, but that
there is a bug in Guile causing the error.

<mark_weaver> fport_fill_input should handle an EINTR error from 'read',
              and restart the read if that happens.

<mark_weaver> by default on some systems, signals cause 'read', 'write',
              and many other system calls to abort and return an EINTR
              error.

<mark_weaver> basically, at the POSIX level, every call to 'read' has to
              be within a little loop that takes care of the EINTR
              problem.

In short, I don't fully understand the innards to have an opinion on
whether this a bug or users should just set the SA_RESTART flag, bug
Mark assures me this is, indeed, a bug.  Any disagreement, take it up
with him. ;)

Regards,
Aidan Gauland




Information forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Thu, 29 Nov 2012 20:22:01 GMT) Full text and rfc822 format available.

Message #8 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Aidan Gauland <aidalgol <at> no8wireless.co.nz>
Cc: "Mark H. Weaver" <mhw <at> netris.org>, 13018 <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Thu, 29 Nov 2012 21:19:48 +0100
Hi!

Aidan Gauland <aidalgol <at> no8wireless.co.nz> skribis:

> <mark_weaver> fport_fill_input should handle an EINTR error from 'read',
>               and restart the read if that happens.
>
> <mark_weaver> by default on some systems, signals cause 'read', 'write',
>               and many other system calls to abort and return an EINTR
>               error.
>
> <mark_weaver> basically, at the POSIX level, every call to 'read' has to
>               be within a little loop that takes care of the EINTR
>               problem.

‘fport_fill_input’ does this:

  SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));

and SCM_SYSCALL does that:

  # ifdef EINTR
  #  if (EINTR > 0)
  #   define SCM_SYSCALL(line)                    \
    do                                            \
      {                                           \
        errno = 0;                                \
        line;                                     \
        if (errno == EINTR)                       \
          {                                       \
            SCM_ASYNC_TICK;                       \
            continue;                             \
          }                                       \
      }                                           \
    while(0)
  #  endif /*  (EINTR > 0) */
  # endif /* def EINTR */

On GNU/Linux, I see:

  $ echo '#include <errno.h>' | gcc -E -dM - | grep EINTR
  #define EINTR 4

So AFAICS, the EINTR case is taken care of.  Or am I missing something?

Do you have a reduced test case?

Thanks,
Ludo’.




Information forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Tue, 05 Mar 2013 18:55:05 GMT) Full text and rfc822 format available.

Message #11 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: Andy Wingo <wingo <at> pobox.com>
To: Aidan Gauland <aidalgol <at> no8wireless.co.nz>
Cc: 13018 <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Tue, 05 Mar 2013 18:57:46 +0100
On Wed 28 Nov 2012 09:19, Aidan Gauland <aidalgol <at> no8wireless.co.nz> writes:

> In a program that maintains a TCP connection with a polling loop, I have
> defined a signal handler with the `sigaction' procedure to terminate the
> connection gracefully.  When the trapped signal is received (in this
> case SIGINT) and the handler called, the following error message is
> printed (full backtrace omitted):
>
> ERROR: In procedure %read-line:
> ERROR: In procedure fport_fill_input: Interrupted system call

Any more info here?

Andy
-- 
http://wingolog.org/




Information forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Wed, 13 Mar 2013 11:46:02 GMT) Full text and rfc822 format available.

Message #14 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: Andy Wingo <wingo <at> pobox.com>
To: ludo <at> gnu.org (Ludovic Courtès)
Cc: "Mark H. Weaver" <mhw <at> netris.org>, 13018 <at> debbugs.gnu.org,
	Aidan Gauland <aidalgol <at> no8wireless.co.nz>
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Wed, 13 Mar 2013 12:44:13 +0100
On Thu 29 Nov 2012 21:19, ludo <at> gnu.org (Ludovic Courtès) writes:

> Aidan Gauland <aidalgol <at> no8wireless.co.nz> skribis:
>
>> <mark_weaver> fport_fill_input should handle an EINTR error from 'read',
>>               and restart the read if that happens.
>>
>> <mark_weaver> by default on some systems, signals cause 'read', 'write',
>>               and many other system calls to abort and return an EINTR
>>               error.
>>
>> <mark_weaver> basically, at the POSIX level, every call to 'read' has to
>>               be within a little loop that takes care of the EINTR
>>               problem.
>
> ‘fport_fill_input’ does this:
>
>   SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));
>
> and SCM_SYSCALL does that:
>
>   # ifdef EINTR
>   #  if (EINTR > 0)
>   #   define SCM_SYSCALL(line)                    \
>     do                                            \
>       {                                           \
>         errno = 0;                                \
>         line;                                     \
>         if (errno == EINTR)                       \
>           {                                       \
>             SCM_ASYNC_TICK;                       \
>             continue;                             \
>           }                                       \
>       }                                           \
>     while(0)
>   #  endif /*  (EINTR > 0) */
>   # endif /* def EINTR */

I get the feeling the EINTR is coming from somewhere else -- like the
ASYNC_TICK.  The sigaction could cause a thunk to run there.

Aidan, do you have a test case?

Andy
-- 
http://wingolog.org/




Information forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Fri, 29 Mar 2013 07:39:03 GMT) Full text and rfc822 format available.

Message #17 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: Aidan Gauland <aidalgol <at> no8wireless.co.nz>
To: Andy Wingo <wingo <at> pobox.com>
Cc: "Mark H. Weaver" <mhw <at> netris.org>,
	Ludovic Courtès <ludo <at> gnu.org>, 13018 <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Fri, 29 Mar 2013 20:35:53 +1300
> Aidan, do you have a test case?

I haven't been able to reproduce this with a minimal example, but I can
consistently reproduce it with my IRC bot
<https://github.com/aidalgol/cunning-bot>.

Replace the last two lines (lines 22 and 23) of run-cbot.scm with...

(define bot (make-bot "Cunning_Bot" "Cunning_Bot" "Cunning Bot" "chat.freenode.net" 6667))
(sigaction SIGINT
  (lambda ()
    (disconnect-bot bot)))
(start-bot bot '("#cunningbot"))

...run it (run-cbot.scm), and after it says

Setting up IRC connection...done.
Joining channels...done.

type ^C

I get this backtrace:

^CBacktrace:
In ice-9/boot-9.scm:
 157: 12 [catch #t #<catch-closure 9a1020> ...]
In unknown file:
   ?: 11 [apply-smob/1 #<catch-closure 9a1020>]
In ice-9/boot-9.scm:
  63: 10 [call-with-prompt prompt0 ...]
In ice-9/eval.scm:
 421: 9 [eval # #]
In ice-9/boot-9.scm:
2131: 8 [save-module-excursion #<procedure 9a01c0 at ice-9/boot-9.scm:3711:3 ()>]
3718: 7 [#<procedure 9a01c0 at ice-9/boot-9.scm:3711:3 ()>]
In unknown file:
   ?: 6 [load-compiled/vm "/home/aidan/.cache/guile/ccache/2.0-LE-8-2.0/home/aidan/src/cunning-bot/run-cbot.scm.go"]
In /home/aidan/src/cunning-bot/bot.scm:
 260: 5 [start-bot # #]
 115: 4 [read-line-irc #]
In ice-9/rdelim.scm:
 129: 3 [read-line #<input-output: socket 11> trim]
In unknown file:
   ?: 2 [%read-line #<input-output: socket 11>]
In ice-9/boot-9.scm:
 184: 1 [throw system-error "fport_fill_input" "~A" ("Interrupted system call") (4)]
In /home/aidan/src/cunning-bot/run-cbot.scm:
  24: 0 [#<procedure 12007a0 at /home/aidan/src/cunning-bot/run-cbot.scm:24:2 ()> 2]

/home/aidan/src/cunning-bot/run-cbot.scm:24:2: In procedure #<procedure 12007a0 at /home/aidan/src/cunning-bot/run-cbot.scm:24:2 ()>:
/home/aidan/src/cunning-bot/run-cbot.scm:24:2: Wrong number of arguments to #<procedure 12007a0 at /home/aidan/src/cunning-bot/run-cbot.scm:24:2 ()>

Could this be caused by a bug in spells?

I wish I could give a simpler test case. :(

Regards,
Aidan Gauland

(Sorry I forgot to group reply the first time.)




Information forwarded to bug-guile <at> gnu.org:
bug#13018; Package guile. (Wed, 03 Jul 2013 19:15:01 GMT) Full text and rfc822 format available.

Message #20 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: Mark H Weaver <mhw <at> netris.org>
To: Aidan Gauland <aidalgol <at> no8wireless.co.nz>,  13018 <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Wed, 03 Jul 2013 15:14:10 -0400
We now finally understand the cause of this bug.  See below.

Andy Wingo <wingo <at> pobox.com> writes:
> On Thu 29 Nov 2012 21:19, ludo <at> gnu.org (Ludovic Courtès) writes:
>
>> Aidan Gauland <aidalgol <at> no8wireless.co.nz> skribis:
>>
>>> <mark_weaver> fport_fill_input should handle an EINTR error from 'read',
>>>               and restart the read if that happens.
>>>
>>> <mark_weaver> by default on some systems, signals cause 'read', 'write',
>>>               and many other system calls to abort and return an EINTR
>>>               error.
>>>
>>> <mark_weaver> basically, at the POSIX level, every call to 'read' has to
>>>               be within a little loop that takes care of the EINTR
>>>               problem.
>>
>> ‘fport_fill_input’ does this:
>>
>>   SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));
>>
>> and SCM_SYSCALL does that:
>>
>>   # ifdef EINTR
>>   #  if (EINTR > 0)
>>   #   define SCM_SYSCALL(line)                    \
>>     do                                            \
>>       {                                           \
>>         errno = 0;                                \
>>         line;                                     \
>>         if (errno == EINTR)                       \
>>           {                                       \
>>             SCM_ASYNC_TICK;                       \
>>             continue;                             \
>>           }                                       \
>>       }                                           \
>>     while(0)
>>   #  endif /*  (EINTR > 0) */
>>   # endif /* def EINTR */
>
> I get the feeling the EINTR is coming from somewhere else [...]

As Ludovic finally realized, the 'continue' above always exits the loop,
because 'continue' jumps to the test, rather than unconditionally
jumping to the top of the loop body.  This bug was introduced in Guile
2.0.0.  We are now discussing how to proceed on guile-devel:

http://lists.gnu.org/archive/html/guile-devel/2013-06/msg00050.html
http://lists.gnu.org/archive/html/guile-devel/2013-07/msg00002.html

    Thanks,
      Mark




Reply sent to Mark H Weaver <mhw <at> netris.org>:
You have taken responsibility. (Thu, 08 Aug 2013 21:41:01 GMT) Full text and rfc822 format available.

Notification sent to Aidan Gauland <aidalgol <at> no8wireless.co.nz>:
bug acknowledged by developer. (Thu, 08 Aug 2013 21:41:02 GMT) Full text and rfc822 format available.

Message #25 received at 13018-done <at> debbugs.gnu.org (full text, mbox):

From: Mark H Weaver <mhw <at> netris.org>
To: Aidan Gauland <aidalgol <at> no8wireless.co.nz>
Cc: 13018-done <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Thu, 08 Aug 2013 17:39:57 -0400
This bug was fixed in fe51c7b3e0a1e93be3bb81dd2d4b18936fe2df3a.

    Thanks!
      Mark




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 06 Sep 2013 11:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 11 years and 346 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.