This is the mail archive of the libc-alpha@sources.redhat.com 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]

Weak linkage of cancellation points.


Hi,

I used to use the fact that all (thread) cancellation points
(tcdrain pread fsync fcntl accept pwrite64 nanosleep read lseek64 pread64 open64 send
pause close open recvfrom recvmsg lseek wait sendmsg recv write sendto msync connect)
could be 'overridden' because they have weak linkage;  I used that fact to
do sanity checks, like that a cleanup handler is installed for a critical
area if the program is inside a critical area
[namely: LIBCWD_ASSERT( __libcwd_tsd.inside_critical_area == __libcwd_tsd.cleanup_handler_installed ||
__libcwd_tsd.cancel_explicitely_disabled || __libcwd_tsd.internal_debugging_code );]

However - as of glib-2.3.3 the *real* cancellation points have been changed
from global, weak linkage to local/hidden.  For example, nm returns
000acfe0 t __libc_close
now, instead of a 'W' there).

I don't understand the rationale behind this hiding - the prefix of __libc_ should
be more than enough gard against accidental use.  Hiding it like this only
criples the flexibility of the library.

Of course, I can still 'override' close() instead of __libc_close(), but that
doesn't work: if glibc calls __libc_close internally then that is a ALSO a cancellation.
You could argue that now every glibc function that calls one of the __libc_ internal
cancellation functions has turned into a cancellation point - but that is not
true: those functions CAN call the cancellation point function perhaps but
do not have to.  A runtime check of the *real* cancellation points is needed.

Moreover - it just doesn't make sense to export functions with weak linkage
when one is not able to catch ALL calls to that function - including the ones
done from libc itself.  The whole point of overriding it is a complete replacement
and a partial replacement will simply not work in many cases.

Finally - I find inconsistencies that I do not understand.  For example, wait() has:

00085da0 W wait
00085da0 W __wait

but waitpid has:

00085e60 W waitpid
00085e60 T __waitpid

Why is __wait weak, and __waitpid not?
Since more __* functions are weak, I'd think that __waitpid should be weak too.

-- 
Carlo Wood <carlo@alinoe.com>


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