Towards heap walk (#569)
* Implement tracking full slabs and large allocations This adds an additional SeqSet that is used to track all the fully used slabs and large allocations. This gives more chances to detect memory leaks, and additionally catch some more UAF failures where the object is not recycled. * Make slabmeta track a slab interior pointer Use the head of the free list builder to track an interior pointer to the slab. This is unused unless the list contains something. Hence, we can use this to represent an interior pointer to the slab and report more accurate leaks. * clangformat * clangtidy * clangtidy * Clang tidy again. * Fixing provenance. * Clangformat * Clang tidy. * Add assert for sanity * Make reinterpret_cast more descriptive. Add an operation to get a tag free pointer from an address_t, and use it * Clangformat * CR * Fix calculation of number of allocations. * Fix calculation of number of allocations. * Fix test
This commit is contained in:
committed by
GitHub
parent
704843d5ff
commit
4e88b42621
@@ -1,16 +1,27 @@
|
||||
#include <snmalloc/snmalloc.h>
|
||||
|
||||
#ifdef SNMALLOC_PASS_THROUGH // This test depends on snmalloc internals
|
||||
int main()
|
||||
{
|
||||
#ifndef SNMALLOC_PASS_THROUGH // This test depends on snmalloc internals
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# include <iostream>
|
||||
# include <snmalloc/snmalloc.h>
|
||||
# include <vector>
|
||||
|
||||
template<size_t size>
|
||||
void debug_check_empty_1()
|
||||
{
|
||||
std::cout << "debug_check_empty_1 " << size << std::endl;
|
||||
snmalloc::Alloc& a = snmalloc::ThreadAlloc::get();
|
||||
bool result;
|
||||
|
||||
auto r = a.alloc(16);
|
||||
auto r = a.alloc(size);
|
||||
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != false)
|
||||
{
|
||||
std::cout << "debug_check_empty failed to detect leaked memory:" << size
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -19,14 +30,17 @@ int main()
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != true)
|
||||
{
|
||||
std::cout << "debug_check_empty failed to say empty:" << size << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
r = a.alloc(16);
|
||||
r = a.alloc(size);
|
||||
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != false)
|
||||
{
|
||||
std::cout << "debug_check_empty failed to detect leaked memory:" << size
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -35,7 +49,70 @@ int main()
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != true)
|
||||
{
|
||||
std::cout << "debug_check_empty failed to say empty:" << size << std::endl;
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
void debug_check_empty_2()
|
||||
{
|
||||
std::cout << "debug_check_empty_2 " << size << std::endl;
|
||||
snmalloc::Alloc& a = snmalloc::ThreadAlloc::get();
|
||||
bool result;
|
||||
std::vector<void*> allocs;
|
||||
// 1GB of allocations
|
||||
size_t count = snmalloc::bits::min<size_t>(2048, 1024 * 1024 * 1024 / size);
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (i % (count / 16) == 0)
|
||||
{
|
||||
std::cout << "." << std::flush;
|
||||
}
|
||||
auto r = a.alloc(size);
|
||||
allocs.push_back(r);
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != false)
|
||||
{
|
||||
std::cout << "False empty after " << i << " allocations of " << size
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (i % (count / 16) == 0)
|
||||
{
|
||||
std::cout << "." << std::flush;
|
||||
}
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
|
||||
if (result != false)
|
||||
{
|
||||
std::cout << "False empty after " << i << " deallocations of " << size
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
a.dealloc(allocs[i]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
snmalloc::debug_check_empty<snmalloc::StandardConfig>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
debug_check_empty_1<16>();
|
||||
debug_check_empty_1<16384>();
|
||||
debug_check_empty_1<65536>();
|
||||
debug_check_empty_1<1024 * 1024 * 32>();
|
||||
|
||||
debug_check_empty_2<32>();
|
||||
debug_check_empty_2<16384>();
|
||||
debug_check_empty_2<65535>();
|
||||
debug_check_empty_2<1024 * 1024 * 32>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user