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