This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: SIGINT, longjmp, getaddrinfo
- From: Michael Kerrisk <mtk dot manpages at gmail dot com>
- To: Hal Murray <hmurray at megapathdsl dot net>
- Cc: libc-help <libc-help at sourceware dot org>, Michael Kerrisk-manpages <mtk dot manpages at gmail dot com>
- Date: Tue, 16 Feb 2016 16:00:05 +0100
- Subject: Re: SIGINT, longjmp, getaddrinfo
- Authentication-results: sourceware.org; auth=none
- References: <carlos at systemhalted dot org> <CAE2sS1jyUtbcZmyX234xJ=7R44=Mt+1tMUh+yJ32OiHt1ro7QA at mail dot gmail dot com> <20160216031136 dot 4E51E406057 at ip-64-139-1-69 dot sjc dot megapath dot net>
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