lua memory leak detection and prevention

(cherry picked from commit cfa9bfa44d)
This commit is contained in:
Matthew Kennedy 2023-03-04 03:33:08 -05:00 committed by Andrey
parent 3221c4c075
commit c70c6ccec5
1 changed files with 34 additions and 8 deletions

View File

@ -29,6 +29,7 @@ public:
size_t m_memoryUsed = 0;
size_t m_size;
char* m_buffer;
void* alloc(size_t n) {
return chHeapAlloc(&m_heap, n);
@ -41,15 +42,17 @@ public:
public:
template<size_t TSize>
Heap(char (&buffer)[TSize])
: m_size(TSize)
{
chHeapObjectInit(&m_heap, buffer, TSize);
reinit(buffer, TSize);
}
void reinit(char *buffer, size_t m_size) {
void reinit(char *buffer, size_t size) {
efiAssertVoid(OBD_PCM_Processor_Fault, m_memoryUsed == 0, "Too late to reinit Lua heap");
chHeapObjectInit(&m_heap, buffer, m_size);
this->m_size = m_size;
m_size = size;
m_buffer = buffer;
reset();
}
void* realloc(void* ptr, size_t osize, size_t nsize) {
@ -88,10 +91,23 @@ public:
size_t used() const {
return m_memoryUsed;
}
// Use only in case of emergency - obliterates all heap objects and starts over
void reset() {
chHeapObjectInit(&m_heap, m_buffer, m_size);
m_memoryUsed = 0;
}
};
static Heap userHeap(luaUserHeap);
static void printLuaMemoryInfo() {
auto heapSize = userHeap.size();
auto memoryUsed = userHeap.used();
float pct = 100.0f * memoryUsed / heapSize;
efiPrintf("Lua memory heap usage: %d / %d bytes = %.1f%%", memoryUsed, heapSize, pct);
}
static void* myAlloc(void* /*ud*/, void* ptr, size_t osize, size_t nsize) {
if (engineConfiguration->debugMode == DBG_LUA) {
engine->outputChannels.debugIntField1 = userHeap.used();
@ -195,7 +211,8 @@ static bool loadScript(LuaHandle& ls, const char* scriptStr) {
}
efiPrintf(TAG "script loaded successfully!");
printLuaMemory();
printLuaMemoryInfo();
return true;
}
@ -329,6 +346,15 @@ void LuaThread::ThreadTask() {
while (!chThdShouldTerminateX()) {
bool wasOk = runOneLua(myAlloc, config->luaScript);
auto usedAfterRun = userHeap.used();
if (usedAfterRun != 0) {
efiPrintf(TAG "MEMORY LEAK DETECTED: %d bytes used after teardown", usedAfterRun);
// Lua blew up in some terrible way that left memory allocated, reset the heap
// so that subsequent runs don't overflow the heap
userHeap.reset();
}
// Reset any lua adjustments the script made
engine->resetLua();
@ -380,8 +406,8 @@ void startLua() {
needsReset = true;
});
addConsoleAction("luamemory", printLuaMemory);
#endif // LUA_USER_HEAP
addConsoleAction("luamemory", printLuaMemoryInfo);
#endif
}
#else // not EFI_UNIT_TEST