[PATCH] D147413: [sanitizer][win] Fix `Atexit()` on MinGW asan_dynamic runtime
Alvin Wong via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 2 08:41:32 PDT 2023
alvinhochun created this revision.
alvinhochun added reviewers: mstorsjo, vitalybuka, glider, kcc.
Herald added a subscriber: Enna1.
Herald added a project: All.
alvinhochun requested review of this revision.
Herald added a project: Sanitizers.
Herald added a subscriber: Sanitizers.
Some functions of asan depends on `Atexit()` handlers. On Windows, this
is implemented in ad3ec82bb1c7217b0187a1e16bb22642e194ce94 to queue the
handlers in a vector then register them with `atexit()` only after the
CRT is fully initialized. However, this is broken on MinGW with
asan_dynamic runtime due to different initialization order. This change
fixes the issue by making sure that `Atexit()` can call `atexit()`
directly past the pre-initialization phase.
This fixes two asan test cases on MinGW.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D147413
Files:
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp
compiler-rt/test/asan/TestCases/atexit_stats.cpp
Index: compiler-rt/test/asan/TestCases/atexit_stats.cpp
===================================================================
--- compiler-rt/test/asan/TestCases/atexit_stats.cpp
+++ 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 <stdlib.h>
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
#include <malloc.h>
Index: compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp
===================================================================
--- compiler-rt/test/asan/TestCases/Windows/coverage-basic.cpp
+++ 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 <stdio.h>
void foo() { fputs("FOO", stderr); }
Index: compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -718,13 +718,26 @@
// atexit() as soon as it is ready for use (i.e. after .CRT$XIC initializers).
InternalMmapVectorNoCtor<void (*)(void)> 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]);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147413.510355.patch
Type: text/x-patch
Size: 2322 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230402/98b92f04/attachment.bin>
More information about the llvm-commits
mailing list