Skip to content

Commit

Permalink
Move double-free reporting to its own method.
Browse files Browse the repository at this point in the history
This allows it to be detected more easily from stack traces and for additional
metadata to be collected during these crashes.

PiperOrigin-RevId: 721134951
Change-Id: I1f9f42063ef667219b9ad41537526423c66e4c56
  • Loading branch information
ckennelly authored and copybara-github committed Jan 29, 2025
1 parent 53974e2 commit c8dfee3
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
10 changes: 9 additions & 1 deletion tcmalloc/tcmalloc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,12 @@ inline sized_ptr_t do_malloc_pages(size_t size, size_t weight, Policy policy) {
return res;
}

ABSL_ATTRIBUTE_NORETURN
ABSL_ATTRIBUTE_NOINLINE
static void ReportDoubleFree(void* ptr) {
TC_BUG("Possible double free detected of %p", ptr);
}

// Handles freeing object that doesn't have size class, i.e. which
// is either large or sampled. We explicitly prevent inlining it to
// keep it out of fast-path. This helps avoid expensive
Expand All @@ -641,7 +647,9 @@ static void InvokeHooksAndFreePages(void* ptr, std::optional<size_t> size) {
// We may also encounter this if we free a pointer that was never allocated
// (it's corrupted, it's an interior pointer to another allocation separated
// by more than kPageSize from the true pointer, etc.).
TC_CHECK_NE(span, nullptr, "Possible double free detected");
if (ABSL_PREDICT_FALSE(span == nullptr)) {
ReportDoubleFree(ptr);
}

MaybeUnsampleAllocation(tc_globals, ptr, size, *span);

Expand Down
10 changes: 4 additions & 6 deletions tcmalloc/testing/memory_errors_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,8 @@ TEST_F(TcMallocTest, DoubleFree) {
::operator delete(buf);
};
EXPECT_DEATH(DoubleFree(),
"span != nullptr|Span::Unsample\\(\\)|Span::IN_USE|"
"InvokeHooksAndFreePages\\(\\)|"
"attempting double-free");
"Span::Unsample\\(\\)|Span::IN_USE|Possible double free "
"detected|attempting double-free");
}

TEST_F(TcMallocTest, LargeDoubleFree) {
Expand All @@ -386,9 +385,8 @@ TEST_F(TcMallocTest, LargeDoubleFree) {
benchmark::DoNotOptimize(buf);
::operator delete(buf);
};
EXPECT_DEATH(
DoubleFree(),
"span != nullptr.*Possible double free detected|attempting double-free");
EXPECT_DEATH(DoubleFree(),
"Possible double free detected|attempting double-free");
}

TEST_F(TcMallocTest, ReallocLarger) {
Expand Down

0 comments on commit c8dfee3

Please sign in to comment.