[PATCH] D60593: [GwpAsan] Introduce GWP-ASan.
Mitch Phillips via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 1 14:08:39 PDT 2019
hctim marked 36 inline comments as done.
hctim added inline comments.
================
Comment at: compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp:114
+ uintptr_t UPtr = reinterpret_cast<uintptr_t>(Ptr);
+ uintptr_t SlotStart = slotToAddr(addrToSlot(UPtr));
+ AllocationMetadata *Meta = addrToMetadata(UPtr);
----------------
vlad.tsyrklevich wrote:
> getPageAddr()
Not equal if `sizeof(Slot) != sizeof(Page)`. Happy to introduce a helper fn for this if you want, but it's used in a single place.
================
Comment at: compiler-rt/lib/gwp_asan/guarded_pool_allocator.h:39
+
+ struct AllocationMetadata {
+ // Maximum number of stack trace frames to collect for allocations + frees.
----------------
vitalybuka wrote:
> can you hide this struct into cpp file and just keep forward declaration here?
See https://reviews.llvm.org/D60593?id=195942#inline-541269. Happy to change.
================
Comment at: compiler-rt/lib/gwp_asan/guarded_pool_allocator.h:78
+ // as this may cause a use-after-free on shutdown.
+ ~GuardedPoolAllocator() = default;
+
----------------
vitalybuka wrote:
> why do you need this this line at all "~GuardedPoolAllocator() = default;"?
It's simply an explicit note to the reader that we have a trivial destructor. If they want to add a d'tor, they'll come to this line and read the note above.
================
Comment at: compiler-rt/lib/gwp_asan/guarded_pool_allocator.h:178
+ // *SlotIndex. Returns false if there are no remaining slots, true otherwise.
+ bool reserveSlot(std::size_t *SlotIndex);
+
----------------
vitalybuka wrote:
> can you avoid output arg by:
> std::size_t reserveSlot();
See https://reviews.llvm.org/D60593#inline-542081
================
Comment at: compiler-rt/lib/gwp_asan/guarded_pool_allocator.h:236
+ // should be sampled when it reaches zero.
+ static TLS_INITIAL_EXEC uint64_t NextSampleCounter;
+
----------------
vitalybuka wrote:
> "static private:" are not very useful
> you can hide them into unnamed namespace of cpp file
`NextSampleCounter` are referenced in `shouldSample()`, which is implemented in the header for inlining reasons.
`SingletonPtr` has been moved.
================
Comment at: compiler-rt/lib/gwp_asan/mutex.h:63
+
+ALWAYS_INLINE void Mutex::yieldProcessor(uint8_t Count) {
+#if defined(__i386__) || defined(__x86_64__)
----------------
vitalybuka wrote:
> do you need yieldProcessor and lockSlow inline?
> maybe move into cpp file to move this ifdefs from header?
http://quick-bench.com/5oJNxyiBe-7KwZ0nMCRDGBaNa5s
Looks like with clang gets a slight perf improvement with inlining, which is extended (to 10% perf improvement) w/ libc++.
Also I'm hesitent to create small cpp files, as per https://reviews.llvm.org/D60593?id=195942#inline-542189.
Okay to leave as is?
================
Comment at: compiler-rt/lib/gwp_asan/random.h:24
+ // xorshift128+ (64-bit output). Avoids multiplication.
+ static ALWAYS_INLINE uint64_t getRandomUnsigned64() {
+ uint64_t A = RandomStateA;
----------------
vitalybuka wrote:
> it's called on slow path when NextSampleCounter == 0
> I don't thins ALWAYS_INLINE will help here.
> just move it into cpp file?
> Also http://quick-bench.com/Jbi9nGqIlAfRkFGHjpJzBVR58Bw
>
> Can you explain why you need own random?
>
Can't use PRNG from libc++, as we have to be c-compatible.
Can't use PRNG from sanitizer_common, as we don't depend on sanitizer_common in the core code.
libc rand() is too slow.
read from /dev/ is too slow.
================
Comment at: compiler-rt/test/gwp_asan/thread_contention.cpp:1
+// REQUIRES: gwp_asan
+// This test ensures that normal allocation/memory access/deallocation works
----------------
vlad.tsyrklevich wrote:
> This tests races in the allocation code but not in the deallocation (and reallocation) code.
I've also added a test that's pretty much ThreadedHighContention.
================
Comment at: compiler-rt/test/gwp_asan/thread_contention.cpp:9
+// RUN: %clangxx_gwp_asan %s -o %t
+// RUN: %env_gwp_asan_options=NumUsableGuardedSlots=32 %t 32
+// RUN: %env_gwp_asan_options=NumUsableGuardedSlots=127 %t 127
----------------
vlad.tsyrklevich wrote:
> I don't think the runtime configuration adds much here anyway. I think you could get rid of both options and just have it allocate a fixed amount (lets say 1024 times) twice (first w/o random eviction and second run with.) It simplifies the test.
>
> If we had access to the underlying allocator we could be cuter and also verify that every available slot was used, but I wouldn't bother otherwise.
The runtime configuration is mostly to avoid the overhead of recompilation. The compilation of this file for a debug build of clang takes 3.5-4s on my machine, and I desperately wanted to avoid that overhead multiple times.
The additional runs have been deleted.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D60593/new/
https://reviews.llvm.org/D60593
More information about the llvm-commits
mailing list