Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 21 May 2021 09:19:18 -0700
From: enh <enh@...gle.com>
To: libc-coord@...ts.openwall.com
Cc: Kostya Serebryany <kcc@...gle.com>
Subject: Re: Thread properties API

here's what's shipping in Android S this year:
https://cs.android.com/android/platform/superproject/+/master:bionic/libc/include/sys/thread_properties.h

On Fri, May 21, 2021 at 9:06 AM Florian Weimer <fweimer@...hat.com> wrote:

> In glibc, we have a historic gap when it comes to access to per-thread
> data that may contain application data.  Such functionality is required
> to support memory leak detectors and conservative garbage collectors
> that need to discover pointer values in TLS data.  The sanitizers
> currently hard-code glibc implementation details (that are not really
> unchanging in practice), and we want to switch to a defined interface
> eventually.
>
> We provide some access to per-thread data using libthread_db, but that
> functionality is incomplete in several ways and not readily consumable
> inside a process.
>
> There is a completely different proposal here:
>
>   <https://sourceware.org/glibc/wiki/ThreadPropertiesAPI>
>
> The interfaces that follow below avoid callback functions that must be
> invoked with internal locks held because that is prone to lead to
> deadlocks.  They also avoid encoding a specific, unchanging layout for
> the static TLS area (which can be extended, but not moved) or internal
> pthread_setspecific tables, or whether any such per-thread data
> structures are allocated by malloc.
>
> I'd appreciate comments on this proposal.  It's very early and I'm not
> entirely convinced yet that it is actually implementable. 8-)
>
> void pthread_retain_np (pthread_t thread);
>
> pthread_retain_np marks THREAD for retention.  A retained thread
> identifier remains valid after the thread has exited and (if joinable)
> has been joined, but all subsequent operations on the thread ID, except
> for pthread_release_np, pthread_getattr_np and pthread_tls_areas_get_np,
> will fail.
>
> void pthread_release_np (pthread_t thread);
>
> pthread_release_np undoes the effect of a previous pthread_retain_np
> call (which can be implied by pthread_all_threads_np).  Every
> pthread_retain_np call must eventually be paired with a
> pthread_release_np call, or otherwise there is a resource leak.
>
> Once the number of pthread_release_np calls is equal to the number of
> pthread_retain_np calls for a particular thread ID (including such calls
> implied by pthread_all_threads_np), the thread ID is again only valid
> while the thread is running or joinable.  If the number of calls it is
> equal, it is undefined to call pthread_release_np.
>
> size_t pthread_all_threads_np (pthread_t *result, size_t length);
>
> pthread_all_threads_np returns the number of all currently running or
> joinable threads in the process.  The identifiers of the first LENGTH
> such threads are written to the array starting at RESULT.  For those
> thread identifiers, pthread_retrain_np is invoked; this happens in such
> a way that the thread is running or joinable at this point.
>
> Applications need to call pthread_release_np on all the thread
> identifiers that pthread_all_threads_np has written to RESULT.  This
> also applies to the case where pthread_all_threads_np is called in a
> loop that grows the RESULT array to the size required to store all
> thread IDs in the current process.
>
> Due to the lack of synchronization, an unspecified time can pass between
> the termination of a detached thread and the time its thread ID no
> longer appears among the thread IDs provided by pthread_all_threads_np.
> It is unspecified whether threads that are neither running nor joinable,
> but have been retained, appear among those thread IDs.
>
> struct pthread_tls_area_np { const void *start; size_t length; };
> size_t pthread_tls_areas_get_np (pthread_t thread,
>   struct pthread_tls_area_np *areas, size_t length);
> size_t pthread_tls_areas_release_np (pthread_t thread,
>   const struct pthread_tls_area_np *areas, size_t count);
>
> pthread_tls_area_get_np returns the number of TLS areas currently
> allocated for THREAD.  This number may be zero if THREAD refers to a
> thread that is not running.  The location and size of up to LENGTH of
> these areas are written to the array starting at AREAS, followed by zero
> elements until LENGTH array elements have been written.  An application
> can detect that the provided array is too small by check the return
> value against LENGTH.
>
> The application may inspect the pointers and memory areas identified by
> the array elements (up to the return value of pthread_tls_area_np).  At
> this point, it is guaranteed that the memory locations remain valid for
> access.  After inspecting the TLS areas, the application must call
> pthread_tls_areas_release_np, passing the same THREAD, AREAS and LENGTH
> arguments that were used in the pthread_tls_areas_get_np.
>
> For example, if it has been previously determined that a __thread
> variable is at address P for a particular THREAD, and if the LENGTH
> argument to pthread_tls_area_np is sufficiently large to hold all TLS
> areas for THREAD, then P will be contain within one of the TLS areas.
> If the implementation supports access to __thread variables from other
> threads, it is safe to access *P, subject to the usual constraints
> regarding data races, until pthread_tls_areas_release_np is called.
> Similarly, pointer values stored by pthread_setspecific will appear in
> the TLS areas at unspecified locations, and the values will be current
> in the sense that if a pthread_setspecific call for a key happens-before
> the pthread_tls_areas_get_np call and the access to the TLS areas
> happens-before the next pthread_setspecific call for that key on the
> thread, then the pointer value stored by the first pthread_setspecific
> call will appear in one of the TLS areas listed by
> pthread_tls_areas_get_np.  However, writes to that pointer value may not
> be reflected in future pthread_getspecific calls (even with
> synchronization).
>
> The distribution of various TLS data structures among the AREAS array is
> unspecified.  Some of the areas may be allocated on the heap using
> malloc, or part of such heap allocations.  It is unspecified whether
> previously allocated TLS areas are returned for a thread that is no
> longer running.  If any per-thread data is allocated by the
> implementation in such a way that it will be deallocated using free,
> pointers to such allocations should appear among the areas returned by
> pthread_tls_areas_get_np, so that internal allocations made by the
> implementation are not falsely flagged as leaked.
>
> Thanks,
> Florian
>
>

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.