[scudo] Align objects with alignas
authorVitaly Buka <vitalybuka@google.com>
Tue, 4 May 2021 23:34:59 +0000 (16:34 -0700)
committerVitaly Buka <vitalybuka@google.com>
Wed, 5 May 2021 20:29:21 +0000 (13:29 -0700)
Operator new must align allocations for types with large alignment.

Before c++17 behavior was implementation defined and both clang and gc++
before 11 ignored alignment. Miss-aligned objects mysteriously crashed
tests on Ubuntu 14.

Alternatives are compile with -std=c++17 or -faligned-new, but they were
discarded as less portable.

Reviewed By: hctim

Differential Revision: https://reviews.llvm.org/D101874

compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
compiler-rt/lib/scudo/standalone/tests/primary_test.cpp

index 5c5f646..5db249d 100644 (file)
@@ -15,6 +15,7 @@
 #include <memory>
 #include <mutex>
 #include <set>
+#include <stdlib.h>
 #include <thread>
 #include <vector>
 
@@ -74,6 +75,14 @@ template <typename Config> struct TestAllocator : scudo::Allocator<Config> {
       this->disableMemoryTagging();
   }
   ~TestAllocator() { this->unmapTestOnly(); }
+
+  void *operator new(size_t size) {
+    void *p = nullptr;
+    EXPECT_EQ(0, posix_memalign(&p, alignof(TestAllocator), size));
+    return p;
+  }
+
+  void operator delete(void *ptr) { free(ptr); }
 };
 
 template <class TypeParam> struct ScudoCombinedTest : public Test {
index d90b6a3..e7aa6f7 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <condition_variable>
 #include <mutex>
+#include <stdlib.h>
 #include <thread>
 #include <vector>
 
@@ -63,6 +64,14 @@ struct SizeClassAllocator<TestConfig1, SizeClassMapT>
 template <typename BaseConfig, typename SizeClassMapT>
 struct TestAllocator : public SizeClassAllocator<BaseConfig, SizeClassMapT> {
   ~TestAllocator() { this->unmapTestOnly(); }
+
+  void *operator new(size_t size) {
+    void *p = nullptr;
+    EXPECT_EQ(0, posix_memalign(&p, alignof(TestAllocator), size));
+    return p;
+  }
+
+  void operator delete(void *ptr) { free(ptr); }
 };
 
 template <class BaseConfig> struct ScudoPrimaryTest : public Test {};