This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: SIGINT, longjmp, getaddrinfo


On Tue, Feb 16, 2016 at 4:11 AM, Hal Murray <hmurray@megapathdsl.net> wrote:
> Thanks for all the replies.
>
>
> carlos@systemhalted.org said:
>> To reiterate: After jumping out of an AS handler you may only call AS-safe
>> functions.
>
> There is no hint of that in my man page for longjmp/siglongjmp.  (Most Linux
> distros have the same page from 2009-01-13.)
>
> It does say:
>        longjmp() and siglongjmp() make programs hard to understand  and  main-
>        tain.  If possible, an alternative should be used.
>
> but I didn't interpret "hard to understand" as hinting at the sorts of
> problems I encountered.

Agreed. That text doesn't really apply to your point. Unfortunately,
the man page was silent on this issue (though I was aware of it).

>
> The NetBSD man page does have an interesting CAVEAT:
>      Use of longjmp() or siglongjmp() from inside a signal handler is not as
>      easy as it might seem.  Generally speaking, all possible code paths
>      between the setjmp() and longjmp() must be signal race safe.
>      Furthermore, the code paths must not do resource management (such as
>      open(2) or close(2)) without blocking the signal in question, or
>      resources might be mismanaged.  Obviously this makes longjmp() much less
>      useful than previously thought.
>
>
> [maybe some routines mask or intercept signals or ...]
> carlos@systemhalted.org said:
>> No code protects against signals like this. It would cause very large signal
>> handling latency e.g. your signal would be pending for a long time while the
>> various library routines finish.
>
> readline installs its own signal handlers.  The man page doesn't mention it,
> but a break at sigprocmask shows it getting called from rl_set_signals and
> google finds
>   2.5 Readline Signal Handling
>   http://www.delorie.com/gnu/docs/readline/rlman_43.html
>
> carlos@systemhalted.org said:
>> Alternatively use threads and pthread_cancel.
>
> That's the cleanest suggestion I've seen so far.
>
>
> godmar@gmail.com said:
>>> To reiterate: After jumping out of an AS handler you may only call
>>> AS-safe functions.
>> That's not always true in my opinion. It's true only if the main code was
>> able to enter any C library function that is not AS-safe.
>
> The man pages for many routines have a section on thread safety.  I don't
> remember ever seeing one on AS safety.

Yep, it is a lack in the man pages generally. But there is a list of
non-async-signal-safe function sin signal(7).

>
>
> godmar@gmail.com said:
>> Personally, though, I agree that the global flag approach will likely be
>> better.
>
> What does something like getnameinfo do when it gets an EINTR  while waiting
> for a packet to arrive?
>
> How does it know that a SIGINT handler set a flag and wants to bail as
> compared to a timer went off and it should continue.
>
> ---------------
>
> I poked around some more.  I think longjmp-ing out of getnameinfo is leaving
> SIGINT masked.  Is that surprising?  or reasonable?  A break at sigprocmask
> found the readline stuff mentioned above but nothing from getnameinfo.  If
> it's interesting, I'll try to put together a simple test program.
>
>
> I'm still surprised that there isn't some web page that documents and
> discusses this whole area.

<Blush> Well, I know there's a book that covers it...

And now I've added this text to the completely revamped setjmp(2) man page[1]:

       POSIX.1-2008  Technical  Corrigendum  2  adds  longjmp() and sigâ
       longjmp() to the list of async-signal-safe  functions.   However,
       the  standard recommends avoiding the use of these functions from
       signal handlers and goes on to point out that if these  functions
       are  called  from  a  signal handler that interrupted a call to a
       non-async-signal-safe function (or some equivalent, such  as  the
       steps  equivalent  to  exit(3)  that occur upon a return from the
       initial call to main()), the behavior is undefined if the program
       subsequently  makes  a call to a non-async-signal-safe.  The only
       way of avoiding undefined behavior is to ensure one of  the  folâ
       lowing:

       *  After  long  jumping from the signal handler, the program does
          not call any  non-async-signal-safe  functions  and  does  not
          return from the initial call to main().

       *  Any  signal whose handler performs a long jump must be blocked
          during every call to a non-async-signal-safe function  and  no
          non-async-signal-safe  functions  are  called  after returning
          from the initial call to main().

Hopefully that covers everyone's concerns.

Cheers,

Michael

[1] http://git.kernel.org/cgit/docs/man-pages/man-pages.git


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]