This is the mail archive of the
mailing list for the glibc project.
Re: proposal: Thread Properties API
- From: Allan McRae <allan at archlinux dot org>
- To: Konstantin Serebryany <konstantin dot s dot serebryany at gmail dot com>, Rich Felker <dalias at libc dot org>
- Cc: Torvald Riegel <triegel at redhat dot com>, Roland McGrath <roland at hack dot frob dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Date: Mon, 19 May 2014 20:21:40 +1000
- Subject: Re: proposal: Thread Properties API
- Authentication-results: sourceware.org; auth=none
- References: <CAGQ9bdxY1AZtcqZ6k1c+kenmTkWU01YQA6LZMzFGdfX5bUe62Q at mail dot gmail dot com> <20140422195129 dot 1BC492C39C5 at topped-with-meat dot com> <CAGQ9bdxTQVeHr31YSFeZbKAzhNSC2HOTeTE=jxaK_y3=UFaCpQ at mail dot gmail dot com> <1398350733 dot 3155 dot 5755 dot camel at triegel dot csb> <CAGQ9bdxV6EqukO8ECNrK87VGbPzZDqdvL8B9S+SjGzFdwHyLcw at mail dot gmail dot com> <20140425194816 dot GS26358 at brightrain dot aerifal dot cx> <CAGQ9bdztydmCgdkW3X7La7nD5+PQk318qeFuhZbeJJAkn_k+aA at mail dot gmail dot com>
On 28/04/14 18:56, Konstantin Serebryany wrote:
> The last bullet (thread death callback) is indeed tricky.
> For me even a much simplified version will work:
> - only one callback is allowed to be registered -- this is a very
> low level interface, normal programs should not need it.
> asan/tsan/msan wlll not work with any other similar tool in one
> process, even with each other, anyway.
> - the callback can be called right after the last tsd dtor and after
> DTLS is destroyed, whichever comes last
> Any comments about the first 3 bullets (stack size, static TLS size,
> DTLS creation/destruction callbacks)?
Pinging this as the discussion seems to have stalled. The code freeze
for 2.20 is ~6 weeks away and this was targeted to be included.
> On Fri, Apr 25, 2014 at 11:48 PM, Rich Felker <firstname.lastname@example.org> wrote:
>> On Fri, Apr 25, 2014 at 02:58:39PM +0400, Konstantin Serebryany wrote:
>>> On Thu, Apr 24, 2014 at 6:45 PM, Torvald Riegel <email@example.com> wrote:
>>>> On Thu, 2014-04-24 at 13:38 +0400, Konstantin Serebryany wrote:
>>>>> ================== Callback for thread exit ==================
>>>>> Tools such as ASAN, MSAN and LSAN need to perform various cleanup
>>>>> actions just before a thread exits.
>>>>> Currently these tools use an ugly hack to get notified about thread's
>>>>> destruction: call pthread_setspecific recursively
>>>>> PTHREAD_DESTRUCTOR_ITERATIONS times; when the
>>>>> PTHREAD_DESTRUCTOR_ITERATIONS-th call is made we consider the thread
>>>>> as dead. A cleaner interface would be much appreciated (not sure if it
>>>>> easy to do or at all possible)
>>>> GCC's libitm uses a similar hack, but checks whether transactions have
>>>> been used since the last round of pthreads TLS destruction.
>>>>> // Register callback to be called right before the thread is totally destroyed.
>>>>> // The callbacks are chained, they are called in the order opposite to
>>>>> the order they were registered.
>>>> I think we need a more detailed contract here. What does "totally
>>>> destroyed" mean?
>>> That's indeed tricky to define.
>>> There is certainly a point of time when thread is still alive (e.g.
>>> the 4-th tsd destructor),
>>> and then there is a another point when it is dead-dead-dead (e.g. when
>>> it's stack is unmaped or reused by another thread).
>> My definition of "totally destroyed" is a point at which the existence
>> of the thread is no longer "observable". Of course then the latter
>> needs a definition; my intent is that "observable" would definitely
>> count any of the standard interfaces, and definitely would not count
>> things like external debuggers. But the interfaces being proposed are
>> themselves problematic in that they provide a way to observe the
>> existence or nonexistence of a thread. Any time you have two or more
>> clients to these interfaces, at least one of them is going to see a
>> wrong result: the thread cannot be "totally destroyed" yet when one
>> client gets the notification, because another client will later
>> observe it as not-yet-destroyed. That's why the whole concept of these
>> proposed interfaces bothers me...
>>>> What's the requirements on the destruction code
>>>> running, especially regarding which other components can be used during
>>> No libc calls in the destruction code.
>> That's a fairly poorly-specified requirement. Does this mean you have
>> to write the code in asm, since the compiler might generate calls to
>> memset, etc.? In any case how do you intend to get the data anywhere
>> useful without libc calls, since you can't do any memory
>> synchronization? Are __sync builtins or C11 atomics a requirement for
>> using these interfaces?
>> It's also insufficient. For example I think you also want to require
>> that TLS isn't accessed, right? And stack protector will access TLS
>> implicitly (although its access is probably harmless).
>>>> For example, how would ASAN/MSAN/LSAN interact with libitm
>>>> if it would use this feature?
>>> Never thought about libitm<=>*san interaction. Do you expect any problem there?
>> I expect problems anywhere the above contract of "totally destroyed"
>> is violated, which would happen whenever there's more than one client
>> interacting with these interfaces, as described above.
>>>> I would guess that we'd need some combination of "stick to limited set
>>>> of features during destruction" and possibly a multi-round destruction
>>>> to get the dependencies sorted (otherwise, we'd need the registration
>>>> order to perfectly match the logical dependencies during destruction).
>>>>> // The callbacks must be registered only before any threads were
>>>>> created, at most 8 callbacks can be registered.
>>>> Why did you include the former constraint? Wouldn't this prevent some
>>>> uses of this feature?
>>>> Why at most 8 callbacks? Arbitrary choice?
>>> 8 is as good a number as 10 or 16. It has to be small constant to
>>> simplify implementation.
>> 1 is probably the only safe number, but I don't think that will make
>> anyone happy...
>>>>> // No signals may arrive during the calls to these callbacks;
>>>>> immediately after the last of these calls the thread is dead.
>>>>> void __libc_register_thread_exit_callback(void (*cb)());
>>>> What happens to those signals? Or is it a requirement on the
>>>> program/... that they shouldn't get any?
>>> Can't we simply ignore all signals in the thread after some point
>>> (like pthread_sigmask)?
>> Signals must be blocked before a thread can be considered "totally
>> destroyed". Otherwise there is a trivial way its existence can be
>> observed by a fully conforming program. This must be done by the
>> implementation before any of the callbacks are called. It probably
>> needs to be done anyway, even without callbacks; I suspect there's a
>> race condition where dynamic TLS might be accessed "too late" in the
>> thread termination if a signal arrives late.