Skip to content

Commit 9a8c27e

Browse files
kdacopybara-github
authored andcommitted
Rework selection of error type to avoid spin lock.
- Remove storage of write_flag from GuardedPageAllocator::SlotMetadata. - Remove method GuardedPageAllocator::SetWriteFlag - Remove refining the return value of GetErrorType (as write_flag is no longer present) - Add refining the error value to the SegVHandler. PiperOrigin-RevId: 573306812 Change-Id: I75d90ac2daeb18a5375dd172b4242bb90d39fcba
1 parent 2ee0510 commit 9a8c27e

File tree

3 files changed

+43
-37
lines changed

3 files changed

+43
-37
lines changed

tcmalloc/guarded_page_allocator.cc

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ GuardedAllocWithStatus GuardedPageAllocator::Allocate(size_t size,
111111
d.alloc_trace.tid = absl::base_internal::GetTID();
112112
d.requested_size = size;
113113
d.allocation_start = reinterpret_cast<uintptr_t>(result);
114-
d.write_flag = WriteFlag::Unknown;
115114

116115
ASSERT(!alignment || d.allocation_start % alignment == 0);
117116
return {result, Profile::Sample::GuardedStatus::Guarded};
@@ -245,13 +244,6 @@ size_t GuardedPageAllocator::SuccessfulAllocations() {
245244
return num_allocation_requests_ - num_failed_allocations_;
246245
}
247246

248-
void GuardedPageAllocator::SetWriteFlag(const void* ptr, WriteFlag write_flag) {
249-
const uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
250-
size_t slot = GetNearestSlot(addr);
251-
absl::base_internal::SpinLockHolder h(&guarded_page_lock_);
252-
data_[slot].write_flag = write_flag;
253-
}
254-
255247
// Maps 2 * total_pages_ + 1 pages so that there are total_pages_ unique pages
256248
// we can return from Allocate with guard pages before and after them.
257249
void GuardedPageAllocator::MapPages() {
@@ -377,34 +369,13 @@ GuardedAllocationsErrorType GuardedPageAllocator::GetErrorType(
377369
if (write_overflow_detected_)
378370
return GuardedAllocationsErrorType::kBufferOverflowOnDealloc;
379371
if (d.dealloc_trace.depth > 0) {
380-
switch (d.write_flag) {
381-
case WriteFlag::Write:
382-
return GuardedAllocationsErrorType::kUseAfterFreeWrite;
383-
case WriteFlag::Read:
384-
return GuardedAllocationsErrorType::kUseAfterFreeRead;
385-
default:
386-
return GuardedAllocationsErrorType::kUseAfterFree;
387-
}
372+
return GuardedAllocationsErrorType::kUseAfterFree;
388373
}
389374
if (addr < d.allocation_start) {
390-
switch (d.write_flag) {
391-
case WriteFlag::Write:
392-
return GuardedAllocationsErrorType::kBufferUnderflowWrite;
393-
case WriteFlag::Read:
394-
return GuardedAllocationsErrorType::kBufferUnderflowRead;
395-
default:
396-
return GuardedAllocationsErrorType::kBufferUnderflow;
397-
}
375+
return GuardedAllocationsErrorType::kBufferUnderflow;
398376
}
399377
if (addr >= d.allocation_start + d.requested_size) {
400-
switch (d.write_flag) {
401-
case WriteFlag::Write:
402-
return GuardedAllocationsErrorType::kBufferOverflowWrite;
403-
case WriteFlag::Read:
404-
return GuardedAllocationsErrorType::kBufferOverflowRead;
405-
default:
406-
return GuardedAllocationsErrorType::kBufferOverflow;
407-
}
378+
return GuardedAllocationsErrorType::kBufferOverflow;
408379
}
409380
return GuardedAllocationsErrorType::kUnknown;
410381
}

tcmalloc/guarded_page_allocator.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,6 @@ class GuardedPageAllocator {
173173

174174
size_t SuccessfulAllocations() ABSL_LOCKS_EXCLUDED(guarded_page_lock_);
175175

176-
void SetWriteFlag(const void* ptr, WriteFlag write_flag)
177-
ABSL_LOCKS_EXCLUDED(guarded_page_lock_);
178-
179176
size_t page_size() const { return page_size_; }
180177

181178
private:
@@ -185,7 +182,6 @@ class GuardedPageAllocator {
185182
GuardedAllocationsStackTrace dealloc_trace;
186183
size_t requested_size = 0;
187184
uintptr_t allocation_start = 0;
188-
WriteFlag write_flag = WriteFlag::Unknown;
189185
};
190186

191187
// Max number of magic bytes we use to detect write-overflows at deallocation.

tcmalloc/segv_handler.cc

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,45 @@ static WriteFlag ExtractWriteFlagFromContext(void* context) {
151151
#endif
152152
}
153153

154+
GuardedAllocationsErrorType RefineErrorTypeBasedOnWriteFlag(
155+
GuardedAllocationsErrorType error, WriteFlag write_flag) {
156+
switch (error) {
157+
case GuardedAllocationsErrorType::kUseAfterFree:
158+
switch (write_flag) {
159+
case WriteFlag::Write:
160+
return GuardedAllocationsErrorType::kUseAfterFreeWrite;
161+
case WriteFlag::Read:
162+
return GuardedAllocationsErrorType::kUseAfterFreeRead;
163+
default:
164+
break;
165+
}
166+
break;
167+
case GuardedAllocationsErrorType::kBufferUnderflow:
168+
switch (write_flag) {
169+
case WriteFlag::Write:
170+
return GuardedAllocationsErrorType::kBufferUnderflowWrite;
171+
case WriteFlag::Read:
172+
return GuardedAllocationsErrorType::kBufferUnderflowRead;
173+
default:
174+
break;
175+
}
176+
break;
177+
case GuardedAllocationsErrorType::kBufferOverflow:
178+
switch (write_flag) {
179+
case WriteFlag::Write:
180+
return GuardedAllocationsErrorType::kBufferOverflowWrite;
181+
case WriteFlag::Read:
182+
return GuardedAllocationsErrorType::kBufferOverflowRead;
183+
default:
184+
break;
185+
}
186+
break;
187+
default:
188+
break;
189+
}
190+
return error;
191+
}
192+
154193
// A SEGV handler that prints stack traces for the allocation and deallocation
155194
// of relevant memory as well as the location of the memory error.
156195
void SegvHandler(int signo, siginfo_t* info, void* context) {
@@ -160,13 +199,13 @@ void SegvHandler(int signo, siginfo_t* info, void* context) {
160199

161200
// Store load/store from context.
162201
WriteFlag write_flag = ExtractWriteFlagFromContext(context);
163-
tc_globals.guardedpage_allocator().SetWriteFlag(fault, write_flag);
164202

165203
GuardedAllocationsStackTrace *alloc_trace, *dealloc_trace;
166204
GuardedAllocationsErrorType error =
167205
tc_globals.guardedpage_allocator().GetStackTraces(fault, &alloc_trace,
168206
&dealloc_trace);
169207
if (error == GuardedAllocationsErrorType::kUnknown) return;
208+
error = RefineErrorTypeBasedOnWriteFlag(error, write_flag);
170209
pid_t current_thread = absl::base_internal::GetTID();
171210
off_t offset;
172211
size_t size;

0 commit comments

Comments
 (0)