On Darwin, TSan was crashing on the first call into the runtime from
any thread created via pthread_create_from_mach_thread() SPI. These
threads were uninitialized, because TSan could not observe their
creation. This meant that TSan crashed for Xcode's SwiftUI preview
(which uses remote code injection).
Threads created via pthread_create_from_mach_thread() bypass the
pthread_create() interceptor / __tsan_thread_start_func() thread
function wrapper that usually ensures that threads are properly
registered. In addition, we don't receive THREAD_CREATE/DESTROY events
in our pthread introspection hooks. The reason for this is that those
would run in the context of the parent mach thread which makes them not
very useful.
Adding an interceptor for this SPI is not sufficient; it is typically
looked up in the parent process and then marshalled into the
instrumented process.
This change uses the following strategy to register these threads. When
observing the THREAD_CREATE event, we attach enough information to the
thread that is being created (using the new
pthread_introspection_setspecific_np() API) so that in THREAD_START
we can identify how the thread that we are on was actually created. For
regular threads and GCD workers there will be identifying information,
for "special" threads (threads for which we are unable to observe
creation, e.g., threads created via pthread_create_from_mach_thread()
from a Mach thread) the absence of this information lets us infer that
they are special.
If pthread_introspection_setspecific_np() is not available (running on
older OS), we fallback to the previous behavior: registering GCD threads
during THREAD_CREATE and doing nothing for THREAD_START.
rdar://58425782
nit: it should be void * not const void * ;) but it really doesn't matter for you