diff --git a/Core/Lock.cpp b/Core/Lock.cpp index 4a3317a0..6203d8d1 100644 --- a/Core/Lock.cpp +++ b/Core/Lock.cpp @@ -110,6 +110,8 @@ void LockClass::TimeoutDeadLock(SpinLockData Lock, uint64_t Timeout) int LockClass::TimeoutLock(const char *FunctionName, uint64_t Timeout) { + if (!TimeManager) + return Lock(FunctionName); LockData.AttemptingToGet = FunctionName; LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0); Atomic Target = 0; diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 4b90f79a..99022616 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -3,6 +3,9 @@ #include #include #include +#ifdef DEBUG +#include +#endif #include "HeapAllocators/Xalloc/Xalloc.hpp" #include "../Library/liballoc_1_1.h" @@ -256,21 +259,47 @@ void *HeapMalloc(size_t Size) SmartLockClass lock___COUNTER__(AllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("malloc(%d)->[%s]", Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + + void *ret = nullptr; + switch (AllocatorType) { - case unlikely(MemoryAllocatorType::Pages): - return KernelAllocator.RequestPages(TO_PAGES(Size)); + case MemoryAllocatorType::Pages: + { + ret = KernelAllocator.RequestPages(TO_PAGES(Size)); + memset(ret, 0, Size); + break; + } case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->malloc(Size); + { + ret = XallocV1Allocator->malloc(Size); + break; + } case MemoryAllocatorType::liballoc11: { - void *ret = PREFIX(malloc)(Size); + ret = PREFIX(malloc)(Size); memset(ret, 0, Size); - return ret; + break; } default: throw; } + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "malloc( %ld )=%p-%p~%p\n\r", Size, ret, (void *)((uintptr_t)ret + Size), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return ret; } void *HeapCalloc(size_t n, size_t Size) @@ -279,12 +308,22 @@ void *HeapCalloc(size_t n, size_t Size) SmartLockClass lock___COUNTER__(AllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("calloc(%d, %d)->[%s]", n, Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + + void *ret = nullptr; + switch (AllocatorType) { - case unlikely(MemoryAllocatorType::Pages): - return KernelAllocator.RequestPages(TO_PAGES(n * Size)); + case MemoryAllocatorType::Pages: + { + ret = KernelAllocator.RequestPages(TO_PAGES(n * Size)); + memset(ret, 0, n * Size); + break; + } case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->calloc(n, Size); + { + ret = XallocV1Allocator->calloc(n, Size); + break; + } case MemoryAllocatorType::liballoc11: { void *ret = PREFIX(calloc)(n, Size); @@ -294,6 +333,22 @@ void *HeapCalloc(size_t n, size_t Size) default: throw; } + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "calloc( %ld %ld )=%p-%p~%p\n\r", n, Size, ret, (void *)((uintptr_t)ret + (n * Size)), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return ret; } void *HeapRealloc(void *Address, size_t Size) @@ -302,12 +357,22 @@ void *HeapRealloc(void *Address, size_t Size) SmartLockClass lock___COUNTER__(AllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("realloc(%#lx, %d)->[%s]", Address, Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + + void *ret = nullptr; + switch (AllocatorType) { case unlikely(MemoryAllocatorType::Pages): - return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak + { + ret = KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak + memset(ret, 0, Size); + break; + } case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->realloc(Address, Size); + { + ret = XallocV1Allocator->realloc(Address, Size); + break; + } case MemoryAllocatorType::liballoc11: { void *ret = PREFIX(realloc)(Address, Size); @@ -317,6 +382,22 @@ void *HeapRealloc(void *Address, size_t Size) default: throw; } + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "realloc( %p %ld )=%p-%p~%p\n\r", Address, Size, ret, (void *)((uintptr_t)ret + Size), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return ret; } void HeapFree(void *Address) @@ -325,18 +406,40 @@ void HeapFree(void *Address) SmartLockClass lock___COUNTER__(AllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("free(%#lx)->[%s]", Address, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "free( %p )~%p\n\r", Address, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + switch (AllocatorType) { case unlikely(MemoryAllocatorType::Pages): + { KernelAllocator.FreePage(Address); // WARNING: Potential memory leak break; + } case MemoryAllocatorType::XallocV1: + { XallocV1Allocator->free(Address); break; + } case MemoryAllocatorType::liballoc11: + { PREFIX(free) (Address); break; + } default: throw; } @@ -348,6 +451,22 @@ void *operator new(size_t Size) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("new(%d)->[%s]", Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "new( %ld )~%p\n\r", Size, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return HeapMalloc(Size); } @@ -357,6 +476,22 @@ void *operator new[](size_t Size) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("new[](%d)->[%s]", Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "new[]( %ld )~%p\n\r", Size, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return HeapMalloc(Size); } @@ -367,6 +502,22 @@ void *operator new(unsigned long Size, std::align_val_t Alignment) #endif memdbg("new(%d, %d)->[%s]", Size, Alignment, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); fixme("operator new with alignment(%#lx) is not implemented", Alignment); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "new( %ld %#lx )~%p\n\r", Size, (uintptr_t)Alignment, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return HeapMalloc(Size); } @@ -376,6 +527,22 @@ void operator delete(void *Pointer) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("delete(%#lx)->[%s]", Pointer, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "delete( %p )~%p\n\r", Pointer, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + HeapFree(Pointer); } @@ -385,6 +552,22 @@ void operator delete[](void *Pointer) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("delete[](%#lx)->[%s]", Pointer, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "delete[]( %p )~%p\n\r", Pointer, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + HeapFree(Pointer); } @@ -394,6 +577,22 @@ void operator delete(void *Pointer, long unsigned int Size) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("delete(%#lx, %d)->[%s]", Pointer, Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "delete( %p %ld )~%p\n\r", Pointer, Size, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + HeapFree(Pointer); UNUSED(Size); } @@ -404,6 +603,22 @@ void operator delete[](void *Pointer, long unsigned int Size) SmartLockClass lock___COUNTER__(OperatorAllocatorLock, (KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown")); #endif memdbg("delete[](%#lx, %d)->[%s]", Pointer, Size, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : "Unknown"); + +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "delete[]( %p %ld )~%p\n\r", Pointer, Size, __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + HeapFree(Pointer); UNUSED(Size); } diff --git a/Kernel.cpp b/Kernel.cpp index ff692450..ed08420c 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -15,6 +15,12 @@ #include "Core/smbios.hpp" #include "Tests/t.h" +#ifdef DEBUG +bool EnableExternalMemoryTracer = false; /* This can be modified while we are debugging with GDB. */ +char mExtTrkLog[MEM_TRK_MAX_SIZE]; +LockClass mExtTrkLock; +#endif + /** * Fennix Kernel * ------------- diff --git a/Library/Convert.cpp b/Library/Convert.cpp index 5a3dd456..e3231393 100644 --- a/Library/Convert.cpp +++ b/Library/Convert.cpp @@ -4,6 +4,9 @@ #include #include #include +#ifdef DEBUG +#include +#endif #include "../kernel.h" @@ -592,7 +595,7 @@ EXTERNC char *ultoa(unsigned long Value, char *Buffer, int Base) EXTERNC void __chk_fail(void) __attribute__((__noreturn__)); -__noreturn static inline void __convert_chk_fail(void) +__noreturn __always_inline static inline void __convert_chk_fail(void) { #if defined(a64) || defined(a32) asmv("int3"); @@ -636,6 +639,21 @@ EXTERNC __no_stack_protector void *__memcpy_chk(void *dest, const void *src, siz if (unlikely(len > slen)) __chk_fail(); +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "memcpy( %p %p %ld %ld )=%p-%p>%p-%p~%p\n\r", dest, src, len, slen, src, (void *)((uintptr_t)src + len), dest, (void *)((uintptr_t)dest + len), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + switch (CPU::CheckSIMD()) { case CPU::x86SIMDType::SIMD_SSE: @@ -688,6 +706,21 @@ EXTERNC __no_stack_protector void *__memset_chk(void *dest, int val, size_t len, if (unlikely(len > slen)) __chk_fail(); +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "memset( %p %d %ld %ld )=%#x>%p-%p~%p\n\r", dest, val, len, slen, val, dest, (void *)((uintptr_t)dest + len), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + switch (CPU::CheckSIMD()) { case CPU::x86SIMDType::SIMD_SSE: @@ -746,6 +779,21 @@ EXTERNC __no_stack_protector void *__memmove_chk(void *dest, const void *src, si if (unlikely(len > slen)) __chk_fail(); +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "memmove( %p %p %ld %ld )=%p-%p>%p-%p~%p\n\r", dest, src, len, slen, dest, (void *)((uintptr_t)dest + len), src, (void *)((uintptr_t)src + len), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + switch (CPU::CheckSIMD()) { case CPU::x86SIMDType::SIMD_SSE: @@ -835,11 +883,41 @@ EXTERNC __no_stack_protector char *__strcpy_chk(char *dest, const char *src, siz #undef memcpy EXTERNC __no_stack_protector void *memcpy(void *dest, const void *src, size_t len) { +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "!memcpy( %p %p %ld )=%p-%p>%p-%p~%p\n\r", dest, src, len, dest, (void *)((uintptr_t)dest + len), src, (void *)((uintptr_t)src + len), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return __memcpy_chk(dest, src, len, __builtin_object_size(dest, 0)); } #undef memset EXTERNC __no_stack_protector void *memset(void *dest, int val, size_t len) { +#ifdef DEBUG + if (EnableExternalMemoryTracer) + { + mExtTrkLock.TimeoutLock(__FUNCTION__, 100000); + sprintf(mExtTrkLog, "!memset( %p %d %ld )=%p-%p~%p\n\r", dest, val, len, dest, (void *)((uintptr_t)dest + len), __builtin_return_address(0)); + for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) + { + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3).Write(mExtTrkLog[i]); + if (mExtTrkLog[i] == '\r') + break; + } + mExtTrkLock.Unlock(); + } +#endif + return __memset_chk(dest, val, len, __builtin_object_size(dest, 0)); } diff --git a/Tests/MemoryAllocation.cpp b/Tests/MemoryAllocation.cpp index 5e044877..38f9a68c 100644 --- a/Tests/MemoryAllocation.cpp +++ b/Tests/MemoryAllocation.cpp @@ -27,8 +27,16 @@ test_mem_new_delete::~test_mem_new_delete() ; } +extern bool EnableExternalMemoryTracer; + void TestMemoryAllocation() { + if (EnableExternalMemoryTracer) + { + debug("The test is disabled when the external memory tracer is enabled."); + return; + } + void *tmpAlloc1 = kmalloc(176); void *tmpAlloc2 = kmalloc(511); void *tmpAlloc3 = kmalloc(1027); diff --git a/kernel.h b/kernel.h index 9d6f624b..82e8c643 100644 --- a/kernel.h +++ b/kernel.h @@ -21,6 +21,14 @@ extern struct BootInfo *bInfo; #ifdef __cplusplus + +#ifdef DEBUG +#define MEM_TRK_MAX_SIZE 0x100 +extern bool EnableExternalMemoryTracer; +extern char mExtTrkLog[]; +extern LockClass mExtTrkLock; +#endif + extern Video::Display *Display; extern SymbolResolver::Symbols *KernelSymbolTable; extern Power::Power *PowerManager;