^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