I've narrowed down a bug in TSan/NetBSD with __cxa_atexit(a,b,NULL) handling. I'm not sure whether the problem is in NetBSD or TSan. extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); TSan intercepts all atexit() and __cxa_atexit() calls and wraps them in setup_at_exit_wrapper(() into a new struct that preserves the original arguments "a" and "b" from __cxa_atexit() / "a" from atexit(). In case of intercepting atexit() calls we end up with __cxa_atexit(x,y,NULL). In libc we handle this variation in the same way as atexit(x) and drop the "y" argument. static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), void *arg, void *dso) { AtExitCtx *ctx = (AtExitCtx*)InternalAlloc(sizeof(AtExitCtx)); ctx->f = f; ctx->arg = arg; Release(thr, pc, (uptr)ctx); // Memory allocation in __cxa_atexit will race with free during exit, // because we do not see synchronization around atexit callback list. ThreadIgnoreBegin(thr, pc); int res = REAL(__cxa_atexit)(at_exit_wrapper, ctx, dso); ThreadIgnoreEnd(thr, pc); return res; } Itanium C++ ABI: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor-motivation Assuming that the problem is in NetBSD, I've verified that this patch works: http://netbsd.org/~kamil/patch-00038-__cxa_atexit.txt
Attachment:
signature.asc
Description: OpenPGP digital signature