forked from Bananymous/banan-os
Kernel: kmalloc now detects corruption
Kmalloc checks if its nodes have corrupted. This was happening because of stack overflow.
This commit is contained in:
parent
809eb2fe3e
commit
a0bd3dc54f
|
@ -4,6 +4,8 @@
|
||||||
#include <kernel/kprint.h>
|
#include <kernel/kprint.h>
|
||||||
#include <kernel/multiboot.h>
|
#include <kernel/multiboot.h>
|
||||||
|
|
||||||
|
#include <kernel/Thread.h>
|
||||||
|
|
||||||
#define MB (1 << 20)
|
#define MB (1 << 20)
|
||||||
|
|
||||||
static constexpr size_t s_kmalloc_min_align = alignof(max_align_t);
|
static constexpr size_t s_kmalloc_min_align = alignof(max_align_t);
|
||||||
|
@ -55,6 +57,7 @@ private:
|
||||||
uint8_t m_data[0];
|
uint8_t m_data[0];
|
||||||
};
|
};
|
||||||
static_assert(sizeof(kmalloc_node) == s_kmalloc_min_align);
|
static_assert(sizeof(kmalloc_node) == s_kmalloc_min_align);
|
||||||
|
|
||||||
struct kmalloc_info
|
struct kmalloc_info
|
||||||
{
|
{
|
||||||
static constexpr uintptr_t base = 0x00400000;
|
static constexpr uintptr_t base = 0x00400000;
|
||||||
|
@ -182,6 +185,32 @@ void kmalloc_dump_info()
|
||||||
kprintln(" free: 0x{8H}", s_kmalloc_fixed_info.free);
|
kprintln(" free: 0x{8H}", s_kmalloc_fixed_info.free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_corrupted()
|
||||||
|
{
|
||||||
|
auto& info = s_kmalloc_info;
|
||||||
|
auto* temp = info.first();
|
||||||
|
for (; temp->end() <= info.end; temp = temp->after());
|
||||||
|
return (uintptr_t)temp != info.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debug_dump()
|
||||||
|
{
|
||||||
|
auto& info = s_kmalloc_info;
|
||||||
|
|
||||||
|
uint32_t used = 0;
|
||||||
|
uint32_t free = 0;
|
||||||
|
|
||||||
|
for (auto* node = info.first(); node->data() <= info.end; node = node->after())
|
||||||
|
{
|
||||||
|
(node->used() ? used : free) += sizeof(kmalloc_node) + node->size_no_align();
|
||||||
|
dprintln("{} node {H} -> {H}", node->used() ? "used" : "free", node->data(), node->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintln("total used: {}", used);
|
||||||
|
dprintln("total free: {}", free);
|
||||||
|
dprintln(" {}", used + free);
|
||||||
|
}
|
||||||
|
|
||||||
static void* kmalloc_fixed()
|
static void* kmalloc_fixed()
|
||||||
{
|
{
|
||||||
auto& info = s_kmalloc_fixed_info;
|
auto& info = s_kmalloc_fixed_info;
|
||||||
|
@ -282,10 +311,7 @@ static void* kmalloc_impl(size_t size, size_t align)
|
||||||
|
|
||||||
void* kmalloc(size_t size)
|
void* kmalloc(size_t size)
|
||||||
{
|
{
|
||||||
void* res = kmalloc(size, s_kmalloc_min_align);
|
return kmalloc(size, s_kmalloc_min_align);
|
||||||
if (res == nullptr)
|
|
||||||
dwarnln("could not allocate {} bytes", size);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool is_power_of_two(size_t value)
|
static constexpr bool is_power_of_two(size_t value)
|
||||||
|
@ -297,7 +323,6 @@ static constexpr bool is_power_of_two(size_t value)
|
||||||
|
|
||||||
void* kmalloc(size_t size, size_t align)
|
void* kmalloc(size_t size, size_t align)
|
||||||
{
|
{
|
||||||
|
|
||||||
const kmalloc_info& info = s_kmalloc_info;
|
const kmalloc_info& info = s_kmalloc_info;
|
||||||
|
|
||||||
if (size == 0 || size >= info.size)
|
if (size == 0 || size >= info.size)
|
||||||
|
@ -316,7 +341,19 @@ void* kmalloc(size_t size, size_t align)
|
||||||
|
|
||||||
if (ptrdiff_t rem = size % s_kmalloc_min_align)
|
if (ptrdiff_t rem = size % s_kmalloc_min_align)
|
||||||
size += s_kmalloc_min_align - rem;
|
size += s_kmalloc_min_align - rem;
|
||||||
return kmalloc_impl(size, align);
|
|
||||||
|
ASSERT(!is_corrupted());
|
||||||
|
|
||||||
|
if (void* res = kmalloc_impl(size, align))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
dwarnln("could not allocate {H} bytes ({} aligned)", size, align);
|
||||||
|
dwarnln(" {6H} free (fixed)", s_kmalloc_fixed_info.free);
|
||||||
|
dwarnln(" {6H} free", s_kmalloc_info.free);
|
||||||
|
debug_dump();
|
||||||
|
Debug::dump_stack_trace();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kfree(void* address)
|
void kfree(void* address)
|
||||||
|
@ -362,6 +399,8 @@ void kfree(void* address)
|
||||||
}
|
}
|
||||||
else if (s_kmalloc_info.base <= address_uint && address_uint < s_kmalloc_info.end)
|
else if (s_kmalloc_info.base <= address_uint && address_uint < s_kmalloc_info.end)
|
||||||
{
|
{
|
||||||
|
ASSERT(!is_corrupted());
|
||||||
|
|
||||||
auto& info = s_kmalloc_info;
|
auto& info = s_kmalloc_info;
|
||||||
|
|
||||||
auto* node = info.from_address(address);
|
auto* node = info.from_address(address);
|
||||||
|
|
Loading…
Reference in New Issue