^C/SIGINT, longjmp, getnameinfo
Hal Murray
hmurray at megapathdsl.net
Mon Feb 22 06:54:57 UTC 2016
I found the glibc-users mailing list. They explained the problem to me. As
far as I can tell, there isn't a clean fix.
The basic problem is that signal handlers can't legally call many routines.
It's similar to the thread-safe issue but not mentioned on individual man
pages. From signal (7):
A signal handler function must be very careful, since processing else-
where may be interrupted at some arbitrary point in the execution of
the program. POSIX has the concept of "safe function". If a signal
interrupts the execution of an unsafe function, and handler calls an
unsafe function, then the behavior of the program is undefined.
That is followed by a list of safe functions.
If you longjmp out of the signal handler, you are still in the restricted
context and can only call safe functions. The glibc version of th eman page
for setjmp/longjmp has been updated to make that clearer. I don't know how
long it takes that to migrate to what distros distribute.
If you want to write solid code, longjmp-ing out of a signal handler is
basically a no-no. If you want to do that, you have to go through your code
and mask interrupts every time you call a function that is not signal-safe or
when you call in to a library/package which might call an unsafe function.
An alternative is for the interrupt handler to just set a flag and teach the
main code to bail from loops if the flag is set. That works as long as you
don't call anything that takes a long time on a human scale. Many routines
that might take a while return EINTR if they get interrupted by a signal.
Unfortunately, getnameinfo doesn't work that way.
Another approach is to put the getnameinfo in a different thread and use
pthread_cancel. Canceling has similar problems so the thread has to mask
getting canceled at the wrong times which means waiting for getnameinfo to
finish. (But since our thread wouldn't be doing anything else, there is no
point in canceling it.) So we would have to set things up so the thread gets
abandoned and cleans up after itself. I'm sure I could write that code, but
it seems unreasonably complicated.
My plan is to set a flag and wait for getnameinfo to finish, and then try it
to see how annoying the wait is. If it takes too long, I'll consider the
separate thread approach. Now I have to find (and test) all the places where
it should check the flag.
--
These are my opinions. I hate spam.
More information about the devel
mailing list