[kutil] Fix failing heap allocator tests
The tests clearly haven't even been built in a while. I've added a helper script to the project root. Also added a kassert() handler that will allow tests to catch or fail on asserts.
This commit is contained in:
@@ -313,7 +313,6 @@ modules:
|
|||||||
deps:
|
deps:
|
||||||
- kutil
|
- kutil
|
||||||
source:
|
source:
|
||||||
- src/tests/address_manager.cpp
|
|
||||||
- src/tests/constexpr_hash.cpp
|
- src/tests/constexpr_hash.cpp
|
||||||
- src/tests/linked_list.cpp
|
- src/tests/linked_list.cpp
|
||||||
- src/tests/logger.cpp
|
- src/tests/logger.cpp
|
||||||
|
|||||||
@@ -77,8 +77,10 @@ heap_allocator::allocate(size_t length)
|
|||||||
if (length == 0)
|
if (length == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const unsigned clz = __builtin_clzll(total);
|
const unsigned clz = __builtin_clzll(total - 1);
|
||||||
const unsigned order = 64 - clz;
|
unsigned order = 64 - clz;
|
||||||
|
if (order < min_order)
|
||||||
|
order = min_order;
|
||||||
|
|
||||||
kassert(order <= max_order, "Tried to allocate a block bigger than max_order");
|
kassert(order <= max_order, "Tried to allocate a block bigger than max_order");
|
||||||
if (order > max_order)
|
if (order > max_order)
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ int signalled = 0;
|
|||||||
void *signalled_at = nullptr;
|
void *signalled_at = nullptr;
|
||||||
|
|
||||||
void *mem_base = nullptr;
|
void *mem_base = nullptr;
|
||||||
|
size_t mem_size = 4 * max_block;
|
||||||
|
|
||||||
|
extern bool ASSERT_EXPECTED;
|
||||||
|
extern bool ASSERT_HAPPENED;
|
||||||
|
|
||||||
std::vector<size_t> sizes = {
|
std::vector<size_t> sizes = {
|
||||||
16000, 8000, 4000, 4000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 150,
|
16000, 8000, 4000, 4000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 150,
|
||||||
@@ -27,9 +31,23 @@ std::vector<size_t> sizes = {
|
|||||||
|
|
||||||
void segfault_handler(int signum, siginfo_t *info, void *ctxp)
|
void segfault_handler(int signum, siginfo_t *info, void *ctxp)
|
||||||
{
|
{
|
||||||
signalled += 1;
|
uintptr_t start = reinterpret_cast<uintptr_t>(mem_base);
|
||||||
|
uintptr_t end = start + mem_size;
|
||||||
|
uintptr_t addr = reinterpret_cast<uintptr_t>(info->si_addr);
|
||||||
|
|
||||||
|
if (addr < start || addr >= end) {
|
||||||
|
CAPTURE( start );
|
||||||
|
CAPTURE( end );
|
||||||
|
CAPTURE( addr );
|
||||||
|
FAIL("Segfaulted outside memory area");
|
||||||
|
}
|
||||||
|
|
||||||
signalled_at = info->si_addr;
|
signalled_at = info->si_addr;
|
||||||
mprotect(signalled_at, max_block, PROT_READ|PROT_WRITE);
|
signalled += 1;
|
||||||
|
if (mprotect(signalled_at, max_block, PROT_READ|PROT_WRITE)) {
|
||||||
|
perror("mprotect");
|
||||||
|
exit(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Buddy blocks tests", "[memory buddy]" )
|
TEST_CASE( "Buddy blocks tests", "[memory buddy]" )
|
||||||
@@ -38,7 +56,7 @@ TEST_CASE( "Buddy blocks tests", "[memory buddy]" )
|
|||||||
unsigned seed = clock::now().time_since_epoch().count();
|
unsigned seed = clock::now().time_since_epoch().count();
|
||||||
std::default_random_engine rng(seed);
|
std::default_random_engine rng(seed);
|
||||||
|
|
||||||
mem_base = aligned_alloc(max_block, max_block * 4);
|
mem_base = aligned_alloc(max_block, mem_size);
|
||||||
|
|
||||||
// Catch segfaults so we can track memory access
|
// Catch segfaults so we can track memory access
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
@@ -59,8 +77,14 @@ TEST_CASE( "Buddy blocks tests", "[memory buddy]" )
|
|||||||
CHECK( signalled == 0 );
|
CHECK( signalled == 0 );
|
||||||
signalled = 0;
|
signalled = 0;
|
||||||
|
|
||||||
|
// Allocating too much should assert
|
||||||
|
ASSERT_EXPECTED = true;
|
||||||
|
void *p = mm.allocate(max_block - hs + 1);
|
||||||
|
REQUIRE( ASSERT_HAPPENED );
|
||||||
|
ASSERT_HAPPENED = false;
|
||||||
|
|
||||||
// Allocating should signal just at the first page.
|
// Allocating should signal just at the first page.
|
||||||
void *p = mm.allocate(max_block - hs);
|
p = mm.allocate(max_block - hs);
|
||||||
CHECK( p == offset_pointer(mem_base, hs) );
|
CHECK( p == offset_pointer(mem_base, hs) );
|
||||||
CHECK( signalled == 1 );
|
CHECK( signalled == 1 );
|
||||||
CHECK( signalled_at == mem_base );
|
CHECK( signalled_at == mem_base );
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ ListContainsMatcher<T> ListContains(const list_node<T> &item)
|
|||||||
return ListContainsMatcher<T>(item);
|
return ListContainsMatcher<T>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Linked list tests", "[containers list]" )
|
TEST_CASE( "Linked list tests", "[containers] [list]" )
|
||||||
{
|
{
|
||||||
linked_list<unsortableT> ulist;
|
linked_list<unsortableT> ulist;
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ TEST_CASE( "Linked list tests", "[containers list]" )
|
|||||||
CHECK_THAT( ulist_reversed, !ListContains(removed) );
|
CHECK_THAT( ulist_reversed, !ListContains(removed) );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Sorted list tests", "[containers list]" )
|
TEST_CASE( "Sorted list tests", "[containers] [list]" )
|
||||||
{
|
{
|
||||||
using clock = std::chrono::system_clock;
|
using clock = std::chrono::system_clock;
|
||||||
unsigned seed = clock::now().time_since_epoch().count();
|
unsigned seed = clock::now().time_since_epoch().count();
|
||||||
|
|||||||
@@ -1,2 +1,29 @@
|
|||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_RUNNER
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include "kutil/assert.h"
|
||||||
|
|
||||||
|
bool ASSERT_EXPECTED = false;
|
||||||
|
bool ASSERT_HAPPENED = false;
|
||||||
|
void test_assert(const char *file, unsigned line, const char *message)
|
||||||
|
{
|
||||||
|
CAPTURE( file );
|
||||||
|
CAPTURE( line );
|
||||||
|
INFO( message );
|
||||||
|
REQUIRE( ASSERT_EXPECTED );
|
||||||
|
ASSERT_EXPECTED = false;
|
||||||
|
ASSERT_HAPPENED = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] ) {
|
||||||
|
kutil::assert_set_callback(test_assert);
|
||||||
|
|
||||||
|
int result = Catch::Session().run( argc, argv );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace kutil {
|
||||||
|
void * kalloc(size_t size) { return malloc(size); }
|
||||||
|
void kfree(void *p) { return free(p); }
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user