diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -718,13 +718,24 @@ // atexit() as soon as it is ready for use (i.e. after .CRT$XIC initializers). InternalMmapVectorNoCtor atexit_functions; -int Atexit(void (*function)(void)) { +static int queueAtexit(void (*function)(void)) { atexit_functions.push_back(function); return 0; } +// If Atexit() is being called after RunAtexit() has already been run, it needs +// to be able to call atexit() directly. Here we use a function ponter to +// switch out its behaviour. +// An example of where this is needed is the asan_dynamic runtime on MinGW-w64. +// On this environment, __asan_init is called during global constructor phase, +// way after calling the .CRT$XID initializer. +static int (*volatile queueOrCallAtExit)(void (*)(void)) = &queueAtexit; + +int Atexit(void (*function)(void)) { return queueOrCallAtExit(function); } + static int RunAtexit() { TraceLoggingUnregister(g_asan_provider); + queueOrCallAtExit = &atexit; int ret = 0; for (uptr i = 0; i < atexit_functions.size(); ++i) { ret |= atexit(atexit_functions[i]); diff --git a/compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp b/compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp --- a/compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp +++ b/compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp @@ -5,9 +5,6 @@ // // RUN: %sancov print *.sancov | FileCheck %s -// FIXME: Investigate failure on MinGW. -// XFAIL: target={{.*-windows-gnu}} - #include void foo() { fputs("FOO", stderr); } diff --git a/compiler-rt/test/asan/TestCases/atexit_stats.cpp b/compiler-rt/test/asan/TestCases/atexit_stats.cpp --- a/compiler-rt/test/asan/TestCases/atexit_stats.cpp +++ b/compiler-rt/test/asan/TestCases/atexit_stats.cpp @@ -6,9 +6,6 @@ // https://code.google.com/p/address-sanitizer/issues/detail?id=263 // UNSUPPORTED: android -// FIXME: Investigate failure on MinGW. -// XFAIL: target={{.*-windows-gnu}} - #include #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__) #include