[clang] 083d151 - Apply https://reviews.llvm.org/D42519

Russell Gallop via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 28 04:22:41 PST 2021


Author: Russell Gallop
Date: 2021-01-07T17:37:18Z
New Revision: 083d1519465718fb7f7bbe65597ffc23e612ba19

URL: https://github.com/llvm/llvm-project/commit/083d1519465718fb7f7bbe65597ffc23e612ba19
DIFF: https://github.com/llvm/llvm-project/commit/083d1519465718fb7f7bbe65597ffc23e612ba19.diff

LOG: Apply https://reviews.llvm.org/D42519

Tell cmake that Scudo is supported on Windows

Tell cmake that Scudo is supported on Linux

Tell MSVC that Scudo is supported

Need to check that this works on Windows

Change Windows allocator size to be 256GB

Enable scudo on Windows properly

Change literal type to avoid cl warning

Auto-add scudo and scudo_cxx when using -sanitize=scudo to help testing.

This is enough for the tests, though doesn't help as much with large programs like LLVM which drive the linker directly
Use same format for adding libraries as asan above

Avoid adding --gc-sections on Windows

Avoid overriding computeHardwareCRC32 on Windows.

This may cause lower performance on Windows, may need another way or
providing this on Windows.

Only enable builtins (actually required for scudo standalone) if compiler supports them

Tests
Rename getpagesize() to avoid naming conflict on Linux

Move setting up signal handler later as this was firing on the malloc

Remove stray change in SanitizerArgs.cpp

Port threads test from pthreads to c++11 threads for portability as new
test cxx_threads.cpp

Moved mutex.lock() up before starting other threads or they may get the
lock first.

Change to mark as unsupported on windows, not just win32

Convert some more tests to unsupported on windows instead of win32

Mark tests as unsupported

Test for minimal runtime unsupported on Windows

Unsupported on Windows as relies on LD_LIBRARY_PATH.
Or maybe could have parts of this running on Windows

Mark dealloc-race.c as unsupported on Windows as requried fork()

Clang format tests

Added: 
    compiler-rt/test/scudo/cxx_threads.cpp

Modified: 
    clang/lib/Driver/ToolChains/MSVC.cpp
    compiler-rt/cmake/config-ix.cmake
    compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
    compiler-rt/lib/scudo/CMakeLists.txt
    compiler-rt/lib/scudo/scudo_allocator.cpp
    compiler-rt/lib/scudo/scudo_crc32.cpp
    compiler-rt/lib/scudo/scudo_new_delete.cpp
    compiler-rt/lib/scudo/scudo_platform.h
    compiler-rt/lib/scudo/scudo_tsd.h
    compiler-rt/lib/scudo/scudo_tsd_shared.cpp
    compiler-rt/lib/scudo/scudo_tsd_shared.inc
    compiler-rt/test/scudo/dealloc-race.c
    compiler-rt/test/scudo/fsanitize.c
    compiler-rt/test/scudo/interface.cpp
    compiler-rt/test/scudo/lit.cfg.py
    compiler-rt/test/scudo/malloc.cpp
    compiler-rt/test/scudo/memalign.c
    compiler-rt/test/scudo/mismatch.cpp
    compiler-rt/test/scudo/overflow.c
    compiler-rt/test/scudo/preload.cpp
    compiler-rt/test/scudo/rss.c
    compiler-rt/test/scudo/secondary.c
    compiler-rt/test/scudo/symbols.test
    compiler-rt/test/scudo/threads.c
    compiler-rt/test/scudo/tsd_destruction.c
    compiler-rt/test/scudo/valloc.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index f4b7a57e0bb7..c954d6d9d3b7 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -446,6 +446,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     }
   }
 
+  if (TC.getSanitizerArgs().needsScudoRt()) {
+    for (const auto &Lib : {"scudo", "scudo_cxx"}) {
+      CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+    }
+    CmdArgs.push_back(Args.MakeArgString("-include:malloc"));
+  }
+
   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
 
   // Control Flow Guard checks
@@ -1403,6 +1410,7 @@ SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
   Res |= SanitizerKind::PointerSubtract;
   Res |= SanitizerKind::Fuzzer;
   Res |= SanitizerKind::FuzzerNoLink;
+  Res |= SanitizerKind::Scudo;
   Res &= ~SanitizerKind::CFIMFCall;
   return Res;
 }

diff  --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index d13e75e41685..eb266ca3a61c 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -58,6 +58,7 @@ check_c_compiler_flag(-ffreestanding         COMPILER_RT_HAS_FFREESTANDING_FLAG)
 check_c_compiler_flag(-std=c11               COMPILER_RT_HAS_STD_C11_FLAG)
 check_cxx_compiler_flag(-fPIC                COMPILER_RT_HAS_FPIC_FLAG)
 check_cxx_compiler_flag(-fPIE                COMPILER_RT_HAS_FPIE_FLAG)
+check_cxx_compiler_flag(-fbuiltin            COMPILER_RT_HAS_FBUILTIN_FLAG)
 check_cxx_compiler_flag(-fno-builtin         COMPILER_RT_HAS_FNO_BUILTIN_FLAG)
 check_cxx_compiler_flag(-fno-exceptions      COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG)
 check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)
@@ -764,7 +765,7 @@ else()
 endif()
 
 if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND
-    OS_NAME MATCHES "Linux|Android|Fuchsia")
+    OS_NAME MATCHES "Linux|Android|Fuchsia|Windows")
   set(COMPILER_RT_HAS_SCUDO TRUE)
 else()
   set(COMPILER_RT_HAS_SCUDO FALSE)

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 281854aff261..ef97b99a7837 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -21,6 +21,13 @@
 #include <psapi.h>
 #include <stdlib.h>
 
+// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036.  See the
+// "Community Additions" comment on MSDN here:
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
+#define SystemFunction036 NTAPI SystemFunction036
+#include <NTSecAPI.h>
+#undef SystemFunction036
+
 #include "sanitizer_common.h"
 #include "sanitizer_file.h"
 #include "sanitizer_libc.h"
@@ -1106,9 +1113,11 @@ void CheckNoDeepBind(const char *filename, int flag) {
   // Do nothing.
 }
 
-// FIXME: implement on this platform.
+#pragma comment(lib, "advapi32.lib")
 bool GetRandom(void *buffer, uptr length, bool blocking) {
-  UNIMPLEMENTED();
+  if (!buffer || !length || length > 256)
+    return false;
+  return RtlGenRandom(buffer, length) != FALSE;
 }
 
 u32 GetNumberOfCPUs() {

diff  --git a/compiler-rt/lib/scudo/CMakeLists.txt b/compiler-rt/lib/scudo/CMakeLists.txt
index c50ea0233fae..b473c23f05c4 100644
--- a/compiler-rt/lib/scudo/CMakeLists.txt
+++ b/compiler-rt/lib/scudo/CMakeLists.txt
@@ -4,7 +4,9 @@ include_directories(..)
 
 set(SCUDO_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 # SANITIZER_COMMON_CFLAGS include -fno-builtin, but we actually want builtins!
-list(APPEND SCUDO_CFLAGS -fbuiltin)
+if (COMPILER_RT_HAS_FBUILTIN_FLAG)
+  list(APPEND SCUDO_CFLAGS -fbuiltin)
+endif()
 append_rtti_flag(OFF SCUDO_CFLAGS)
 
 set(SCUDO_MINIMAL_DYNAMIC_LIBS ${SANITIZER_COMMON_LINK_LIBS})
@@ -17,7 +19,9 @@ append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fno-omit-frame-pointer
 
 set(SCUDO_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
 # Use gc-sections by default to avoid unused code being pulled in.
-list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -Wl,--gc-sections)
+if (!WIN32)
+  list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -Wl,--gc-sections)
+endif()
 
 if(ANDROID)
 # Put most Sanitizer shared libraries in the global group. For more details, see

diff  --git a/compiler-rt/lib/scudo/scudo_allocator.cpp b/compiler-rt/lib/scudo/scudo_allocator.cpp
index c6a3309cb925..dd07db32af00 100644
--- a/compiler-rt/lib/scudo/scudo_allocator.cpp
+++ b/compiler-rt/lib/scudo/scudo_allocator.cpp
@@ -44,6 +44,12 @@ static u32 Cookie;
 // at compilation or at runtime.
 static atomic_uint8_t HashAlgorithm = { CRC32Software };
 
+#if !SANITIZER_SUPPORTS_WEAK_HOOKS
+SANITIZER_WEAK_ATTRIBUTE u32 computeHardwareCRC32(u32 Crc, uptr Data) {
+  return computeSoftwareCRC32(Crc, Data);
+}
+#endif
+
 inline u32 computeCRC32(u32 Crc, uptr Value, uptr *Array, uptr ArraySize) {
   // If the hardware CRC32 feature is defined here, it was enabled everywhere,
   // as opposed to only for scudo_crc32.cpp. This means that other hardware
@@ -609,7 +615,7 @@ NOINLINE void Allocator::performSanityChecks() {
   // last size class minus the header size, in multiples of MinAlignment.
   UnpackedHeader Header = {};
   const uptr MaxPrimaryAlignment =
-      1 << MostSignificantSetBitIndex(SizeClassMap::kMaxSize - MinAlignment);
+      (uptr)1U << MostSignificantSetBitIndex(SizeClassMap::kMaxSize - MinAlignment);
   const uptr MaxOffset =
       (MaxPrimaryAlignment - Chunk::getHeaderSize()) >> MinAlignmentLog;
   Header.Offset = MaxOffset;

diff  --git a/compiler-rt/lib/scudo/scudo_crc32.cpp b/compiler-rt/lib/scudo/scudo_crc32.cpp
index 87473505fe79..0176f13849c3 100644
--- a/compiler-rt/lib/scudo/scudo_crc32.cpp
+++ b/compiler-rt/lib/scudo/scudo_crc32.cpp
@@ -15,10 +15,13 @@
 
 namespace __scudo {
 
+// Can't override this with weak symbols on Windows
+#if !defined(_WIN32)
 #if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 u32 computeHardwareCRC32(u32 Crc, uptr Data) {
   return CRC32_INTRINSIC(Crc, Data);
 }
 #endif  // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif  // defined(_WIN32)
 
 }  // namespace __scudo

diff  --git a/compiler-rt/lib/scudo/scudo_new_delete.cpp b/compiler-rt/lib/scudo/scudo_new_delete.cpp
index 03eef7f28bb9..8dfc559940e5 100644
--- a/compiler-rt/lib/scudo/scudo_new_delete.cpp
+++ b/compiler-rt/lib/scudo/scudo_new_delete.cpp
@@ -19,7 +19,32 @@
 
 using namespace __scudo;
 
+// C++ operators can't have dllexport attributes on Windows. We export them
+// anyway by passing extra -export flags to the linker, which is exactly that
+// dllexport would normally do. We need to export them in order to make the
+// VS2015 dynamic CRT (MD) work.
+#if SANITIZER_WINDOWS
+#define CXX_OPERATOR_ATTRIBUTE
+#define COMMENT_EXPORT(sym) __pragma(comment(linker, "/export:" sym))
+#ifdef _WIN64
+COMMENT_EXPORT("??2 at YAPEAX_K@Z")                    // operator new
+COMMENT_EXPORT("??2 at YAPEAX_KAEBUnothrow_t@std@@@Z") // operator new nothrow
+COMMENT_EXPORT("??3 at YAXPEAX@Z")                     // operator delete
+COMMENT_EXPORT("??3 at YAXPEAX_K@Z")                   // sized operator delete
+COMMENT_EXPORT("??_U at YAPEAX_K@Z")                   // operator new[]
+COMMENT_EXPORT("??_V at YAXPEAX@Z")                    // operator delete[]
+#else
+COMMENT_EXPORT("??2 at YAPAXI@Z")                   // operator new
+COMMENT_EXPORT("??2 at YAPAXIABUnothrow_t@std@@@Z") // operator new nothrow
+COMMENT_EXPORT("??3 at YAXPAX@Z")                   // operator delete
+COMMENT_EXPORT("??3 at YAXPAXI@Z")                  // sized operator delete
+COMMENT_EXPORT("??_U at YAPAXI@Z")                  // operator new[]
+COMMENT_EXPORT("??_V at YAXPAX@Z")                  // operator delete[]
+#endif
+#undef COMMENT_EXPORT
+#else
 #define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
+#endif
 
 // Fake std::nothrow_t to avoid including <new>.
 namespace std {

diff  --git a/compiler-rt/lib/scudo/scudo_platform.h b/compiler-rt/lib/scudo/scudo_platform.h
index 07d4b70fc8e9..00dcc1e4f2e1 100644
--- a/compiler-rt/lib/scudo/scudo_platform.h
+++ b/compiler-rt/lib/scudo/scudo_platform.h
@@ -16,29 +16,26 @@
 
 #include "sanitizer_common/sanitizer_allocator.h"
 
-#if !SANITIZER_LINUX && !SANITIZER_FUCHSIA
+#if !SANITIZER_LINUX && !SANITIZER_FUCHSIA && !SANITIZER_WINDOWS
 # error "The Scudo hardened allocator is not supported on this platform."
 #endif
 
-#define SCUDO_TSD_EXCLUSIVE_SUPPORTED (!SANITIZER_ANDROID && !SANITIZER_FUCHSIA)
+#define SCUDO_TSD_EXCLUSIVE_SUPPORTED                                          \
+  (!SANITIZER_ANDROID && !SANITIZER_FUCHSIA && !SANITIZER_WINDOWS)
 
 #ifndef SCUDO_TSD_EXCLUSIVE
 // SCUDO_TSD_EXCLUSIVE wasn't defined, use a default TSD model for the platform.
-# if SANITIZER_ANDROID || SANITIZER_FUCHSIA
-// Android and Fuchsia use a pool of TSDs shared between threads.
-#  define SCUDO_TSD_EXCLUSIVE 0
-# elif SANITIZER_LINUX && !SANITIZER_ANDROID
-// Non-Android Linux use an exclusive TSD per thread.
+#if SCUDO_TSD_EXCLUSIVE_SUPPORTED
 #  define SCUDO_TSD_EXCLUSIVE 1
 # else
-#  error "No default TSD model defined for this platform."
-# endif  // SANITIZER_ANDROID || SANITIZER_FUCHSIA
-#endif  // SCUDO_TSD_EXCLUSIVE
-
+#define SCUDO_TSD_EXCLUSIVE 0
+#endif // SCUDO_TSD_EXCLUSIVE_SUPPORTED
+#else
 // If the exclusive TSD model is chosen, make sure the platform supports it.
 #if SCUDO_TSD_EXCLUSIVE && !SCUDO_TSD_EXCLUSIVE_SUPPORTED
 # error "The exclusive TSD model is not supported on this platform."
 #endif
+#endif // SCUDO_TSD_EXCLUSIVE
 
 // Maximum number of TSDs that can be created for the Shared model.
 #ifndef SCUDO_SHARED_TSD_POOL_SIZE
@@ -71,6 +68,8 @@ namespace __scudo {
 const uptr AllocatorSize = 0x4000000000ULL;  // 256G.
 # elif defined(__aarch64__)
 const uptr AllocatorSize = 0x10000000000ULL;  // 1T.
+#elif SANITIZER_WINDOWS
+const uptr AllocatorSize = 0x4000000000ULL; // 256G.
 # else
 const uptr AllocatorSize = 0x40000000000ULL;  // 4T.
 # endif

diff  --git a/compiler-rt/lib/scudo/scudo_tsd.h b/compiler-rt/lib/scudo/scudo_tsd.h
index ec8dabc1f8a7..07b225037451 100644
--- a/compiler-rt/lib/scudo/scudo_tsd.h
+++ b/compiler-rt/lib/scudo/scudo_tsd.h
@@ -18,7 +18,11 @@
 #include "scudo_allocator.h"
 #include "scudo_utils.h"
 
+#if !SANITIZER_WINDOWS
 #include <pthread.h>
+#else
+#include <windows.h>
+#endif // SANITIZER_WINDOWS
 
 namespace __scudo {
 

diff  --git a/compiler-rt/lib/scudo/scudo_tsd_shared.cpp b/compiler-rt/lib/scudo/scudo_tsd_shared.cpp
index 59ad2549998c..81f80bbead7a 100644
--- a/compiler-rt/lib/scudo/scudo_tsd_shared.cpp
+++ b/compiler-rt/lib/scudo/scudo_tsd_shared.cpp
@@ -16,8 +16,13 @@
 
 namespace __scudo {
 
+#if !SANITIZER_WINDOWS
 static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
 pthread_key_t PThreadKey;
+#else
+DWORD TlsIndex = TLS_OUT_OF_INDEXES;
+static INIT_ONCE InitOnce = INIT_ONCE_STATIC_INIT;
+#endif
 
 static atomic_uint32_t CurrentIndex;
 static ScudoTSD *TSDs;
@@ -31,7 +36,12 @@ THREADLOCAL ScudoTSD *CurrentTSD;
 #endif
 
 static void initOnce() {
+#if SANITIZER_WINDOWS
+  TlsIndex = TlsAlloc();
+  CHECK_NE(TlsIndex, TLS_OUT_OF_INDEXES);
+#elif !SANITIZER_ANDROID
   CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0);
+#endif
   initScudo();
   NumberOfTSDs = Min(Max(1U, GetNumberOfCPUsCached()),
                      static_cast<u32>(SCUDO_SHARED_TSD_POOL_SIZE));
@@ -48,7 +58,9 @@ static void initOnce() {
 }
 
 ALWAYS_INLINE void setCurrentTSD(ScudoTSD *TSD) {
-#if SANITIZER_ANDROID
+#if SANITIZER_WINDOWS
+  CHECK(TlsSetValue(TlsIndex, reinterpret_cast<LPVOID>(TSD)));
+#elif SANITIZER_ANDROID
   *get_android_tls_ptr() = reinterpret_cast<uptr>(TSD);
 #elif SANITIZER_LINUX
   CurrentTSD = TSD;
@@ -57,8 +69,20 @@ ALWAYS_INLINE void setCurrentTSD(ScudoTSD *TSD) {
 #endif  // SANITIZER_ANDROID
 }
 
+#if SANITIZER_WINDOWS
+static BOOL CALLBACK handleInit(PINIT_ONCE InitOnce, PVOID Parameter,
+                                PVOID *Context) {
+  initOnce();
+  return TRUE;
+}
+#endif
+
 void initThread(bool MinimalInit) {
+#if SANITIZER_WINDOWS
+  CHECK(InitOnceExecuteOnce(&InitOnce, handleInit, nullptr, nullptr));
+#else
   pthread_once(&GlobalInitialized, initOnce);
+#endif
   // Initial context assignment is done in a plain round-robin fashion.
   u32 Index = atomic_fetch_add(&CurrentIndex, 1, memory_order_relaxed);
   setCurrentTSD(&TSDs[Index % NumberOfTSDs]);

diff  --git a/compiler-rt/lib/scudo/scudo_tsd_shared.inc b/compiler-rt/lib/scudo/scudo_tsd_shared.inc
index 8f3362dd3d71..d96f88918269 100644
--- a/compiler-rt/lib/scudo/scudo_tsd_shared.inc
+++ b/compiler-rt/lib/scudo/scudo_tsd_shared.inc
@@ -16,7 +16,11 @@
 
 #if !SCUDO_TSD_EXCLUSIVE
 
+#if SANITIZER_WINDOWS
+extern DWORD TlsIndex;
+#elif !SANITIZER_ANDROID
 extern pthread_key_t PThreadKey;
+#endif
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
 __attribute__((tls_model("initial-exec")))
@@ -24,7 +28,9 @@ extern THREADLOCAL ScudoTSD *CurrentTSD;
 #endif
 
 ALWAYS_INLINE ScudoTSD* getCurrentTSD() {
-#if SANITIZER_ANDROID
+#if SANITIZER_WINDOWS
+  return reinterpret_cast<ScudoTSD *>(TlsGetValue(TlsIndex));
+#elif SANITIZER_ANDROID
   return reinterpret_cast<ScudoTSD *>(*get_android_tls_ptr());
 #elif SANITIZER_LINUX
   return CurrentTSD;

diff  --git a/compiler-rt/test/scudo/cxx_threads.cpp b/compiler-rt/test/scudo/cxx_threads.cpp
new file mode 100644
index 000000000000..5261ce3f1f5e
--- /dev/null
+++ b/compiler-rt/test/scudo/cxx_threads.cpp
@@ -0,0 +1,73 @@
+// RUN: %clangxx_scudo %s -o %t
+// RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0"     %run %t 5 1000000 2>&1
+// RUN: %env_scudo_opts="QuarantineSizeKb=1024:ThreadLocalQuarantineSizeKb=64" %run %t 5 1000000 2>&1
+
+// Tests parallel allocations and deallocations of memory chunks from a number
+// of concurrent threads, with and without quarantine.
+// This test passes if everything executes properly without crashing.
+
+#include <assert.h>
+#include <condition_variable>
+#include <stdio.h>
+#include <stdlib.h>
+#include <thread>
+
+#include <sanitizer/allocator_interface.h>
+
+int num_threads;
+int total_num_alloc;
+const int kMaxNumThreads = 500;
+std::thread thread[kMaxNumThreads];
+
+std::condition_variable cond;
+std::mutex mutex;
+char go = 0;
+
+void *thread_fun(void *arg) {
+  mutex.lock();
+  while (!go) {
+    std::unique_lock<std::mutex> lk(mutex);
+    cond.wait(lk);
+  }
+
+  mutex.unlock();
+  for (int i = 0; i < total_num_alloc / num_threads; i++) {
+    void *p = malloc(10);
+    __asm__ __volatile__(""
+                         :
+                         : "r"(p)
+                         : "memory");
+    free(p);
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  assert(argc == 3);
+  num_threads = atoi(argv[1]);
+  assert(num_threads > 0);
+  assert(num_threads <= kMaxNumThreads);
+  total_num_alloc = atoi(argv[2]);
+  assert(total_num_alloc > 0);
+
+  printf("%d threads, %d allocations in each\n", num_threads,
+         total_num_alloc / num_threads);
+  fprintf(stderr, "Heap size before: %zd\n", __sanitizer_get_heap_size());
+  fprintf(stderr, "Allocated bytes before: %zd\n",
+          __sanitizer_get_current_allocated_bytes());
+
+  mutex.lock();
+  for (int i = 0; i < num_threads; i++)
+    thread[i] = std::thread(thread_fun, (void *)0);
+  go = 1;
+  cond.notify_all();
+  mutex.unlock();
+  for (int i = 0; i < num_threads; i++)
+    thread[i].join();
+
+  fprintf(stderr, "Heap size after: %zd\n", __sanitizer_get_heap_size());
+  fprintf(stderr, "Allocated bytes after: %zd\n",
+          __sanitizer_get_current_allocated_bytes());
+
+  return 0;
+}

diff  --git a/compiler-rt/test/scudo/dealloc-race.c b/compiler-rt/test/scudo/dealloc-race.c
index 326e22f27373..f75dcd5578cf 100644
--- a/compiler-rt/test/scudo/dealloc-race.c
+++ b/compiler-rt/test/scudo/dealloc-race.c
@@ -1,3 +1,5 @@
+// UNSUPPORTED: windows
+
 // RUN: %clang_scudo %s -O2 -o %t
 // RUN: %env_scudo_opts="QuarantineChunksUpToSize=0" %run %t 2>&1
 

diff  --git a/compiler-rt/test/scudo/fsanitize.c b/compiler-rt/test/scudo/fsanitize.c
index 7e5d5451f726..9df060f926e7 100644
--- a/compiler-rt/test/scudo/fsanitize.c
+++ b/compiler-rt/test/scudo/fsanitize.c
@@ -1,5 +1,7 @@
 // Test various -fsanitize= additional flags combinations.
 
+// UNSUPPORTED: windows
+
 // RUN: %clang_scudo %s -o %t
 // RUN: not %run %t 2>&1 | FileCheck %s
 

diff  --git a/compiler-rt/test/scudo/interface.cpp b/compiler-rt/test/scudo/interface.cpp
index ec7375193e12..91fc8b104169 100644
--- a/compiler-rt/test/scudo/interface.cpp
+++ b/compiler-rt/test/scudo/interface.cpp
@@ -10,13 +10,30 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#if defined(_WIN32)
+#include <windows.h>
+#else
 #include <unistd.h>
+#endif
 
 #include <vector>
 
 #include <sanitizer/allocator_interface.h>
 #include <sanitizer/scudo_interface.h>
 
+#if defined(_MSC_VER)
+#include <BaseTsd.h>
+typedef SSIZE_T ssize_t;
+#endif
+
+void sleep_ms(unsigned int ms) {
+#if defined(_WIN32)
+  Sleep(ms);
+#else
+  usleep(ms * 1000U);
+#endif
+}
+
 int main(int argc, char **argv)
 {
   assert(argc == 2);
@@ -57,7 +74,7 @@ int main(int argc, char **argv)
     }
     // Set the soft RSS limit to 1Mb.
     __scudo_set_rss_limit(1, 0);
-    usleep(20000);
+    sleep_ms(200);
     // The following allocation should return NULL.
     void *p = malloc(size);
     assert(!p);
@@ -83,7 +100,7 @@ int main(int argc, char **argv)
     }
     // Set the hard RSS limit to 1Mb
     __scudo_set_rss_limit(1, 1);
-    usleep(20000);
+    sleep_ms(200);
     // The following should trigger our death.
     void *p = malloc(size);
   }

diff  --git a/compiler-rt/test/scudo/lit.cfg.py b/compiler-rt/test/scudo/lit.cfg.py
index 236d645f3b94..9fb76522b9e0 100644
--- a/compiler-rt/test/scudo/lit.cfg.py
+++ b/compiler-rt/test/scudo/lit.cfg.py
@@ -17,19 +17,22 @@
 
 # C & CXX flags.
 c_flags = ([config.target_cflags] +
-           ["-pthread",
-           "-fPIE",
-           "-pie",
-           "-O0",
-           "-UNDEBUG",
-           "-ldl",
-           "-Wl,--gc-sections"])
+           ["-O0",
+            "-UNDEBUG"])
 
-# Android doesn't want -lrt.
-if not config.android:
-  c_flags += ["-lrt"]
+if config.host_os != 'Windows':
+  c_flags += ["-pthread",
+              "-fPIE",
+              "-pie",
+              "-ldl",
+              "-Wl,--gc-sections"]
+  # Android doesn't want -lrt.
+  if not config.android:
+    c_flags += ["-lrt"]
 
-cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++11"])
+cxx_flags = (c_flags + config.cxx_mode_flags)
+if config.host_os != 'Windows':
+  cxx_flags += ["-std=c++11"]
 
 scudo_flags = ["-fsanitize=scudo"]
 
@@ -59,6 +62,6 @@ def build_invocation(compile_flags):
 config.substitutions.append(('%env_scudo_opts=',
                              'env SCUDO_OPTIONS=' + default_scudo_opts))
 
-# Hardened Allocator tests are currently supported on Linux only.
-if config.host_os not in ['Linux']:
+# Hardened Allocator tests are currently supported on Linux and Windows only.
+if config.host_os not in ['Linux', 'Windows']:
    config.unsupported = True

diff  --git a/compiler-rt/test/scudo/malloc.cpp b/compiler-rt/test/scudo/malloc.cpp
index 6c6a6c464f29..0f38ae81bad1 100644
--- a/compiler-rt/test/scudo/malloc.cpp
+++ b/compiler-rt/test/scudo/malloc.cpp
@@ -11,6 +11,11 @@
 
 #include <vector>
 
+#if defined(_MSC_VER)
+#include <BaseTsd.h>
+typedef SSIZE_T ssize_t;
+#endif
+
 int main(int argc, char **argv)
 {
   void *p;

diff  --git a/compiler-rt/test/scudo/memalign.c b/compiler-rt/test/scudo/memalign.c
index 675f53415193..04ab95e7452f 100644
--- a/compiler-rt/test/scudo/memalign.c
+++ b/compiler-rt/test/scudo/memalign.c
@@ -5,6 +5,7 @@
 // RUN:                                             not %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s
 // RUN: %env_scudo_opts=DeallocationTypeMismatch=1  not %run %t realloc     2>&1 | FileCheck --check-prefix=CHECK-realloc %s
 // RUN: %env_scudo_opts=DeallocationTypeMismatch=0      %run %t realloc     2>&1
+// UNSUPPORTED: windows
 
 // Tests that the various aligned allocation functions work as intended. Also
 // tests for the condition where the alignment is not a power of 2.

diff  --git a/compiler-rt/test/scudo/mismatch.cpp b/compiler-rt/test/scudo/mismatch.cpp
index b794f66d8a4e..7c80febf9c33 100644
--- a/compiler-rt/test/scudo/mismatch.cpp
+++ b/compiler-rt/test/scudo/mismatch.cpp
@@ -28,4 +28,3 @@ int main(int argc, char **argv)
 }
 
 // CHECK-dealloc: ERROR: allocation type mismatch when deallocating address
-// CHECK-realloc: ERROR: allocation type mismatch when reallocating address

diff  --git a/compiler-rt/test/scudo/overflow.c b/compiler-rt/test/scudo/overflow.c
index c5a58f87f305..341aa4bdad27 100644
--- a/compiler-rt/test/scudo/overflow.c
+++ b/compiler-rt/test/scudo/overflow.c
@@ -8,6 +8,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+#if defined(_MSC_VER)
+#include <BaseTsd.h>
+typedef SSIZE_T ssize_t;
+#endif
+
 int main(int argc, char **argv)
 {
   ssize_t offset = sizeof(void *) == 8 ? 8 : 0;

diff  --git a/compiler-rt/test/scudo/preload.cpp b/compiler-rt/test/scudo/preload.cpp
index 7fa8df4c6931..e09d9d0aa3dd 100644
--- a/compiler-rt/test/scudo/preload.cpp
+++ b/compiler-rt/test/scudo/preload.cpp
@@ -5,7 +5,7 @@
 // RUN: env LD_PRELOAD=%shared_minlibscudo not %run %t 2>&1 | FileCheck %s
 
 // This way of setting LD_PRELOAD does not work with Android test runner.
-// REQUIRES: !android
+// UNSUPPORTED: android, windows
 
 #include <assert.h>
 

diff  --git a/compiler-rt/test/scudo/rss.c b/compiler-rt/test/scudo/rss.c
index 0b76857b9a4d..abc2f644e95b 100644
--- a/compiler-rt/test/scudo/rss.c
+++ b/compiler-rt/test/scudo/rss.c
@@ -20,19 +20,31 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if defined(_WIN32)
+#include <windows.h>
+#else
 #include <unistd.h>
+#endif
 
 static const size_t kNumAllocs = 64;
 static const size_t kAllocSize = 1 << 20;  // 1MB.
 
 static void *allocs[kNumAllocs];
 
+void sleep_ms(unsigned int ms) {
+#if defined(_WIN32)
+  Sleep(ms);
+#else
+  usleep(ms * 1000U);
+#endif
+}
+
 int main(int argc, char *argv[]) {
   int returned_null = 0;
   for (int i = 0; i < kNumAllocs; i++) {
     // sleep for 100ms every 8 allocations, to allow the RSS check to catch up.
     if (i != 0 && (i & 0x7) == 0)
-      usleep(100000);
+      sleep_ms(100);
     allocs[i] = malloc(kAllocSize);
     if (allocs[i])
       memset(allocs[i], 0xff, kAllocSize);  // Dirty the pages.

diff  --git a/compiler-rt/test/scudo/secondary.c b/compiler-rt/test/scudo/secondary.c
index b770ca076b70..cc1a6346065e 100644
--- a/compiler-rt/test/scudo/secondary.c
+++ b/compiler-rt/test/scudo/secondary.c
@@ -6,37 +6,60 @@
 // allocated by the Secondary allocator, or writing too far in front of it.
 
 #include <assert.h>
-#include <malloc.h>
-#include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <signal.h>
 #include <unistd.h>
+#endif
 
+#ifdef _WIN32
+DWORD getsystempagesize() {
+  SYSTEM_INFO si;
+  GetSystemInfo(&si);
+  return si.dwPageSize;
+}
+LONG WINAPI handler(EXCEPTION_POINTERS *ExceptionInfo) {
+  fprintf(stderr, "AccessViolation\n");
+  ExitProcess(0);
+}
+#else
 void handler(int signo, siginfo_t *info, void *uctx) {
   if (info->si_code == SEGV_ACCERR) {
-    fprintf(stderr, "SCUDO SIGSEGV\n");
+    fprintf(stderr, "AccessViolation\n");
     exit(0);
   }
   exit(1);
 }
+long getsystempagesize() {
+  return sysconf(_SC_PAGESIZE);
+}
+#endif
 
 int main(int argc, char **argv)
 {
   // The size must be large enough to be serviced by the secondary allocator.
-  long page_size = sysconf(_SC_PAGESIZE);
-  size_t size = (1U << 17) + page_size;
-  struct sigaction a;
+  long page_size = getsystempagesize();
+  size_t size = (1U << 19) + page_size;
 
   assert(argc == 2);
-  memset(&a, 0, sizeof(a));
-  a.sa_sigaction = handler;
-  a.sa_flags = SA_SIGINFO;
 
   char *p = (char *)malloc(size);
   assert(p);
   memset(p, 'A', size); // This should not trigger anything.
   // Set up the SIGSEGV handler now, as the rest should trigger an AV.
+#ifdef _WIN32
+  SetUnhandledExceptionFilter(handler);
+#else
+  struct sigaction a = {0};
+  a.sa_sigaction = handler;
+  a.sa_flags = SA_SIGINFO;
   sigaction(SIGSEGV, &a, NULL);
+#endif
+
   if (!strcmp(argv[1], "after")) {
     for (int i = 0; i < page_size; i++)
       p[size + i] = 'A';
@@ -50,4 +73,4 @@ int main(int argc, char **argv)
   return 1; // A successful test means we shouldn't reach this.
 }
 
-// CHECK: SCUDO SIGSEGV
+// CHECK: AccessViolation

diff  --git a/compiler-rt/test/scudo/symbols.test b/compiler-rt/test/scudo/symbols.test
index 0425e62ba6af..aba6a60d227a 100644
--- a/compiler-rt/test/scudo/symbols.test
+++ b/compiler-rt/test/scudo/symbols.test
@@ -1,4 +1,4 @@
-UNSUPPORTED: android
+UNSUPPORTED: android, windows
 
 Verify that various functions are *not* present in the minimal binary. Presence
 of those symbols in the minimal runtime would mean that the split code made it

diff  --git a/compiler-rt/test/scudo/threads.c b/compiler-rt/test/scudo/threads.c
index b34e6f0f79a2..9b6e4c0e1968 100644
--- a/compiler-rt/test/scudo/threads.c
+++ b/compiler-rt/test/scudo/threads.c
@@ -1,6 +1,7 @@
 // RUN: %clang_scudo %s -o %t
 // RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0"     %run %t 5 1000000 2>&1
 // RUN: %env_scudo_opts="QuarantineSizeKb=1024:ThreadLocalQuarantineSizeKb=64" %run %t 5 1000000 2>&1
+// UNSUPPORTED: windows
 
 // Tests parallel allocations and deallocations of memory chunks from a number
 // of concurrent threads, with and without quarantine.

diff  --git a/compiler-rt/test/scudo/tsd_destruction.c b/compiler-rt/test/scudo/tsd_destruction.c
index 1b0d0eff9f11..d4a9a067eee5 100644
--- a/compiler-rt/test/scudo/tsd_destruction.c
+++ b/compiler-rt/test/scudo/tsd_destruction.c
@@ -1,5 +1,6 @@
 // RUN: %clang_scudo %s -o %t
 // RUN: %run %t 2>&1
+// UNSUPPORTED: windows
 
 #include <locale.h>
 #include <pthread.h>

diff  --git a/compiler-rt/test/scudo/valloc.c b/compiler-rt/test/scudo/valloc.c
index 605b9c4d4b9d..db516641d13f 100644
--- a/compiler-rt/test/scudo/valloc.c
+++ b/compiler-rt/test/scudo/valloc.c
@@ -2,7 +2,7 @@
 // RUN:                                                 %run %t valid   2>&1
 // RUN:                                             not %run %t invalid 2>&1 | FileCheck %s
 // RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid 2>&1
-// UNSUPPORTED: android
+// UNSUPPORTED: android, windows
 
 // Tests that valloc and pvalloc work as intended.
 


        


More information about the cfe-commits mailing list