[compiler-rt] 04e42f6 - Revert "[GWP-ASan] Move random-related code in the allocator"
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 22 12:58:59 PDT 2020
Author: Nikita Popov
Date: 2020-10-22T21:56:37+02:00
New Revision: 04e42f62548d4c0367664188a938b609435718e2
URL: https://github.com/llvm/llvm-project/commit/04e42f62548d4c0367664188a938b609435718e2
DIFF: https://github.com/llvm/llvm-project/commit/04e42f62548d4c0367664188a938b609435718e2.diff
LOG: Revert "[GWP-ASan] Move random-related code in the allocator"
This reverts commit 9903b0586cfb76ef2401c342501e61e1bd3daa0f.
Causes build failures (on GCC 10.2) with the following error:
In file included from /home/nikic/llvm-project/compiler-rt/lib/scudo/standalone/combined.h:29,
from /home/nikic/llvm-project/compiler-rt/lib/scudo/standalone/allocator_config.h:12,
from /home/nikic/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp:14:
/home/nikic/llvm-project/compiler-rt/lib/scudo/standalone/../../gwp_asan/guarded_pool_allocator.h: In member function ‘bool gwp_asan::GuardedPoolAllocator::shouldSample()’:
/home/nikic/llvm-project/compiler-rt/lib/scudo/standalone/../../gwp_asan/guarded_pool_allocator.h:82:69: error: conversion from ‘uint32_t’ {aka ‘unsigned int’} to ‘unsigned int:31’ may change value [-Werror=conversion]
82 | (getRandomUnsigned32() % (AdjustedSampleRatePlusOne - 1)) + 1;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
Added:
compiler-rt/lib/gwp_asan/random.cpp
compiler-rt/lib/gwp_asan/random.h
Modified:
compiler-rt/lib/gwp_asan/CMakeLists.txt
compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
compiler-rt/lib/gwp_asan/options.inc
compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/gwp_asan/CMakeLists.txt b/compiler-rt/lib/gwp_asan/CMakeLists.txt
index 6bfb3cab13ef..60efc8a39e62 100644
--- a/compiler-rt/lib/gwp_asan/CMakeLists.txt
+++ b/compiler-rt/lib/gwp_asan/CMakeLists.txt
@@ -10,6 +10,7 @@ set(GWP_ASAN_SOURCES
platform_specific/mutex_posix.cpp
platform_specific/utilities_posix.cpp
guarded_pool_allocator.cpp
+ random.cpp
stack_trace_compressor.cpp
utilities.cpp
)
@@ -22,6 +23,7 @@ set(GWP_ASAN_HEADERS
mutex.h
options.h
options.inc
+ random.h
stack_trace_compressor.h
utilities.h
)
diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
index 93fe5c25259d..b2602e4caa59 100644
--- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
+++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
@@ -10,6 +10,7 @@
#include "gwp_asan/optional/segv_handler.h"
#include "gwp_asan/options.h"
+#include "gwp_asan/random.h"
#include "gwp_asan/utilities.h"
// RHEL creates the PRIu64 format macro (for printing uint64_t's) only when this
@@ -37,6 +38,15 @@ namespace {
// referenced by users outside this translation unit, in order to avoid
// init-order-fiasco.
GuardedPoolAllocator *SingletonPtr = nullptr;
+
+class ScopedBoolean {
+public:
+ ScopedBoolean(bool &B) : Bool(B) { Bool = true; }
+ ~ScopedBoolean() { Bool = false; }
+
+private:
+ bool &Bool;
+};
} // anonymous namespace
// Gets the singleton implementation of this class. Thread-compatible until
@@ -54,7 +64,7 @@ void GuardedPoolAllocator::init(const options::Options &Opts) {
return;
Check(Opts.SampleRate >= 0, "GWP-ASan Error: SampleRate is < 0.");
- Check(Opts.SampleRate < (1 << 30), "GWP-ASan Error: SampleRate is >= 2^30.");
+ Check(Opts.SampleRate <= INT32_MAX, "GWP-ASan Error: SampleRate is > 2^31.");
Check(Opts.MaxSimultaneousAllocations >= 0,
"GWP-ASan Error: MaxSimultaneousAllocations is < 0.");
@@ -145,15 +155,13 @@ static uintptr_t getPageAddr(uintptr_t Ptr, uintptr_t PageSize) {
void *GuardedPoolAllocator::allocate(size_t Size) {
// GuardedPagePoolEnd == 0 when GWP-ASan is disabled. If we are disabled, fall
// back to the supporting allocator.
- if (State.GuardedPagePoolEnd == 0) {
- ThreadLocals.NextSampleCounter = AdjustedSampleRatePlusOne - 1;
+ if (State.GuardedPagePoolEnd == 0)
return nullptr;
- }
// Protect against recursivity.
if (ThreadLocals.RecursiveGuard)
return nullptr;
- ScopedRecursiveGuard SRG;
+ ScopedBoolean SB(ThreadLocals.RecursiveGuard);
if (Size == 0 || Size > State.maximumAllocationSize())
return nullptr;
@@ -233,7 +241,7 @@ void GuardedPoolAllocator::deallocate(void *Ptr) {
// Ensure that the unwinder is not called if the recursive flag is set,
// otherwise non-reentrant unwinders may deadlock.
if (!ThreadLocals.RecursiveGuard) {
- ScopedRecursiveGuard SRG;
+ ScopedBoolean B(ThreadLocals.RecursiveGuard);
Meta->DeallocationTrace.RecordBacktrace(Backtrace);
}
}
@@ -278,15 +286,6 @@ void GuardedPoolAllocator::freeSlot(size_t SlotIndex) {
FreeSlots[FreeSlotsLength++] = SlotIndex;
}
-uint32_t GuardedPoolAllocator::getRandomUnsigned32() {
- uint32_t RandomState = ThreadLocals.RandomState;
- RandomState ^= RandomState << 13;
- RandomState ^= RandomState >> 17;
- RandomState ^= RandomState << 5;
- ThreadLocals.RandomState = RandomState;
- return RandomState;
-}
-
GWP_ASAN_TLS_INITIAL_EXEC
GuardedPoolAllocator::ThreadLocalPackedVariables
GuardedPoolAllocator::ThreadLocals;
diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
index cf31437feae6..12049e1ab9d1 100644
--- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
+++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
@@ -13,6 +13,7 @@
#include "gwp_asan/definitions.h"
#include "gwp_asan/mutex.h"
#include "gwp_asan/options.h"
+#include "gwp_asan/random.h"
#include "gwp_asan/stack_trace_compressor.h"
#include <stddef.h>
@@ -194,40 +195,17 @@ class GuardedPoolAllocator {
// the same cache line for performance reasons. These are the most touched
// variables in GWP-ASan.
struct alignas(8) ThreadLocalPackedVariables {
- constexpr ThreadLocalPackedVariables()
- : RandomState(0xff82eb50), NextSampleCounter(0), RecursiveGuard(false) {
- }
- // Initialised to a magic constant so that an uninitialised GWP-ASan won't
- // regenerate its sample counter for as long as possible. The xorshift32()
- // algorithm used below results in getRandomUnsigned32(0xff82eb50) ==
- // 0xfffffea4.
- uint32_t RandomState;
+ constexpr ThreadLocalPackedVariables() {}
// Thread-local decrementing counter that indicates that a given allocation
// should be sampled when it reaches zero.
- uint32_t NextSampleCounter : 31;
+ uint32_t NextSampleCounter = 0;
// Guard against recursivity. Unwinders often contain complex behaviour that
// may not be safe for the allocator (i.e. the unwinder calls dlopen(),
// which calls malloc()). When recursive behaviour is detected, we will
// automatically fall back to the supporting allocator to supply the
// allocation.
- bool RecursiveGuard : 1;
+ bool RecursiveGuard = false;
};
- static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t),
- "thread local data does not fit in a uint64_t");
-
- class ScopedRecursiveGuard {
- public:
- ScopedRecursiveGuard() { ThreadLocals.RecursiveGuard = true; }
- ~ScopedRecursiveGuard() { ThreadLocals.RecursiveGuard = false; }
- };
-
- // Initialise the PRNG, platform-specific.
- void initPRNG();
-
- // xorshift (32-bit output), extremely fast PRNG that uses arithmetic
- // operations only. Seeded using platform-specific mechanisms by initPRNG().
- uint32_t getRandomUnsigned32();
-
static GWP_ASAN_TLS_INITIAL_EXEC ThreadLocalPackedVariables ThreadLocals;
};
} // namespace gwp_asan
diff --git a/compiler-rt/lib/gwp_asan/options.inc b/compiler-rt/lib/gwp_asan/options.inc
index c81e1f47c722..6cdddfbad84d 100644
--- a/compiler-rt/lib/gwp_asan/options.inc
+++ b/compiler-rt/lib/gwp_asan/options.inc
@@ -29,7 +29,7 @@ GWP_ASAN_OPTION(int, MaxSimultaneousAllocations, 16,
GWP_ASAN_OPTION(int, SampleRate, 5000,
"The probability (1 / SampleRate) that an allocation is "
"selected for GWP-ASan sampling. Default is 5000. Sample rates "
- "up to (2^30 - 1) are supported.")
+ "up to (2^31 - 1) are supported.")
// Developer note - This option is not actually processed by GWP-ASan itself. It
// is included here so that a user can specify whether they want signal handlers
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp
index c2cd24454fa2..a8767a4cb808 100644
--- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp
+++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp
@@ -16,7 +16,6 @@
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
-#include <time.h>
#include <unistd.h>
#ifdef ANDROID
@@ -34,11 +33,6 @@ void MaybeSetMappingName(void *Mapping, size_t Size, const char *Name) {
}
namespace gwp_asan {
-
-void GuardedPoolAllocator::initPRNG() {
- ThreadLocals.RandomState = time(nullptr) + getThreadID();
-}
-
void *GuardedPoolAllocator::mapMemory(size_t Size, const char *Name) const {
void *Ptr =
mmap(nullptr, Size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
diff --git a/compiler-rt/lib/gwp_asan/random.cpp b/compiler-rt/lib/gwp_asan/random.cpp
new file mode 100644
index 000000000000..927709abc42b
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/random.cpp
@@ -0,0 +1,29 @@
+//===-- random.cpp ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gwp_asan/random.h"
+#include "gwp_asan/common.h"
+
+#include <time.h>
+
+// Initialised to a magic constant so that an uninitialised GWP-ASan won't
+// regenerate its sample counter for as long as possible. The xorshift32()
+// algorithm used below results in getRandomUnsigned32(0xff82eb50) ==
+// 0xfffffea4.
+GWP_ASAN_TLS_INITIAL_EXEC uint32_t RandomState = 0xff82eb50;
+
+namespace gwp_asan {
+void initPRNG() { RandomState = time(nullptr) + getThreadID(); }
+
+uint32_t getRandomUnsigned32() {
+ RandomState ^= RandomState << 13;
+ RandomState ^= RandomState >> 17;
+ RandomState ^= RandomState << 5;
+ return RandomState;
+}
+} // namespace gwp_asan
diff --git a/compiler-rt/lib/gwp_asan/random.h b/compiler-rt/lib/gwp_asan/random.h
new file mode 100644
index 000000000000..953b98909e95
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/random.h
@@ -0,0 +1,23 @@
+//===-- random.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef GWP_ASAN_RANDOM_H_
+#define GWP_ASAN_RANDOM_H_
+
+#include <stdint.h>
+
+namespace gwp_asan {
+// Initialise the PRNG, using time and thread ID as the seed.
+void initPRNG();
+
+// xorshift (32-bit output), extremely fast PRNG that uses arithmetic operations
+// only. Seeded using walltime.
+uint32_t getRandomUnsigned32();
+} // namespace gwp_asan
+
+#endif // GWP_ASAN_RANDOM_H_
More information about the llvm-commits
mailing list