exception handling predicament
David Miller
davem@davemloft.net
Fri Aug 19 15:36:00 GMT 2011
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 19 Aug 2011 17:11:55 +0200
> Most of glibc doesn't allow pthread_cancel unwidning to occur asynchronously
> though, only pthread_setcanceltype and the syscalls code (usually in
> assembly) and other lowlevel code. You aren't allowed to call most of glibc
> functions with PTHREAD_CANCEL_ASYNCHRONOUS cancel type, and usually a
> cancellation point doesn't occur in the same function as cleanup. The
> cleanup attribute has been designed for what glibc uses it for, so it
> certainly should be used for that.
The whole tree has to be audited for this situation, and aio_suspend.c
is not the only culprit.
> If aio_suspend.c is the only spot where a cancellation point happens in the
> same function as corresponding cleanups, then IMHO the best fix is just to
> make sure it is in a different function (with noinline attribute, not marked
> as nothrow), which will be the cancellation point. glibc is built with
> -fasynchronous-unwind-tables, so it isn't about .eh_frame, just about
> .gcc_except_table.
It is not only aio_suspend.c, here are a few others I was able to spot
very quickly. There are probably several others:
nptl/sysdeps/unix/sysv/linux/sem_wait.c
nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c
nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c
There are alsosome internal pthread routines that match this problem
scenerio, but they work because inside of NPTL a different NPTL
internal cancellation mechanism is used that is not implemented using
the __cleanup__ attribute. These routines are:
nptl/pthread_timedjoin.c
nptl/pthread_join.c
nptl/pthread_cond_wait.c
nptl/pthread_cond_timedwait.c
However, we always have to keep in mind, therefore, that the
pthread_cleanup_{push,pop}() implementations in nptl/pthreadP.h can
never be converted over to __cleanup__ without dealing with the above
cases.
More information about the Libc-alpha
mailing list