2020-10-03 15:22:44 +00:00
|
|
|
#include "global.h"
|
|
|
|
#include "vt.h"
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
StackEntry* sStackInfoListStart = NULL;
|
|
|
|
StackEntry* sStackInfoListEnd = NULL;
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
void StackCheck_Init(StackEntry* entry, void* stackTop, void* stackBottom, u32 initValue, s32 minSpace,
|
|
|
|
const char* name) {
|
2020-03-17 04:31:30 +00:00
|
|
|
StackEntry* iter;
|
|
|
|
u32* addr;
|
|
|
|
|
2021-02-14 00:49:40 +00:00
|
|
|
if (entry == NULL) {
|
2020-03-17 04:31:30 +00:00
|
|
|
sStackInfoListStart = NULL;
|
2020-03-22 21:19:43 +00:00
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
entry->head = (u32)stackTop;
|
|
|
|
entry->tail = (u32)stackBottom;
|
|
|
|
entry->initValue = initValue;
|
|
|
|
entry->minSpace = minSpace;
|
|
|
|
entry->name = name;
|
|
|
|
iter = sStackInfoListStart;
|
2020-03-22 21:19:43 +00:00
|
|
|
while (iter) {
|
|
|
|
if (iter == entry) {
|
2020-03-17 04:31:30 +00:00
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "stackcheck_init: %08x は既にリスト中にある\n" VT_RST, entry);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
2020-03-22 21:19:43 +00:00
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
entry->prev = sStackInfoListEnd;
|
|
|
|
entry->next = NULL;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
|
|
|
if (sStackInfoListEnd) {
|
2020-03-17 04:31:30 +00:00
|
|
|
sStackInfoListEnd->next = entry;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
sStackInfoListEnd = entry;
|
2020-03-22 21:19:43 +00:00
|
|
|
if (!sStackInfoListStart) {
|
2020-03-17 04:31:30 +00:00
|
|
|
sStackInfoListStart = entry;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
if (entry->minSpace != -1) {
|
2020-03-17 04:31:30 +00:00
|
|
|
addr = (u32*)entry->head;
|
2020-03-22 21:19:43 +00:00
|
|
|
while ((u32)addr < entry->tail) {
|
2020-03-17 04:31:30 +00:00
|
|
|
*addr++ = entry->initValue;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
void StackCheck_Cleanup(StackEntry* entry) {
|
2020-03-17 04:31:30 +00:00
|
|
|
bool inconsistency = false;
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
if (!entry->prev) {
|
|
|
|
if (entry == sStackInfoListStart) {
|
2020-03-17 04:31:30 +00:00
|
|
|
sStackInfoListStart = entry->next;
|
2020-03-22 21:19:43 +00:00
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
inconsistency = true;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
entry->prev->next = entry->next;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
if (!entry->next) {
|
|
|
|
if (entry == sStackInfoListEnd) {
|
2020-03-17 04:31:30 +00:00
|
|
|
sStackInfoListEnd = entry->prev;
|
2020-03-22 21:19:43 +00:00
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
inconsistency = true;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
}
|
2020-03-22 21:19:43 +00:00
|
|
|
if (inconsistency) {
|
2020-03-17 04:31:30 +00:00
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "stackcheck_cleanup: %08x リスト不整合です\n" VT_RST, entry);
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
}
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
StackStatus StackCheck_GetState(StackEntry* entry) {
|
2020-03-17 04:31:30 +00:00
|
|
|
u32* last;
|
|
|
|
u32 used;
|
|
|
|
u32 free;
|
|
|
|
s32 ret;
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
for (last = (u32*)entry->head; (u32)last < entry->tail; last++) {
|
|
|
|
if (entry->initValue != *last) {
|
2020-03-17 04:31:30 +00:00
|
|
|
break;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
used = entry->tail - (u32)last;
|
|
|
|
free = (u32)last - entry->head;
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
if (free == 0) {
|
2020-03-17 04:31:30 +00:00
|
|
|
ret = STACK_STATUS_OVERFLOW;
|
|
|
|
osSyncPrintf(VT_FGCOL(RED));
|
2021-02-14 00:49:40 +00:00
|
|
|
} else if (free < (u32)entry->minSpace && entry->minSpace != -1) {
|
2020-03-17 04:31:30 +00:00
|
|
|
ret = STACK_STATUS_WARNING;
|
|
|
|
osSyncPrintf(VT_FGCOL(YELLOW));
|
2020-03-22 21:19:43 +00:00
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
osSyncPrintf(VT_FGCOL(GREEN));
|
|
|
|
ret = STACK_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
osSyncPrintf("head=%08x tail=%08x last=%08x used=%08x free=%08x [%s]\n", entry->head, entry->tail, last, used, free,
|
2021-10-03 03:17:09 +00:00
|
|
|
entry->name != NULL ? entry->name : "(null)");
|
2020-03-17 04:31:30 +00:00
|
|
|
osSyncPrintf(VT_RST);
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
if (ret != STACK_STATUS_OK) {
|
2020-03-17 04:31:30 +00:00
|
|
|
LogUtils_LogHexDump(entry->head, entry->tail - entry->head);
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-02-14 00:49:40 +00:00
|
|
|
u32 StackCheck_CheckAll(void) {
|
2020-03-17 04:31:30 +00:00
|
|
|
u32 ret = 0;
|
|
|
|
StackEntry* iter = sStackInfoListStart;
|
2021-02-14 00:49:40 +00:00
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
while (iter) {
|
2020-03-17 04:31:30 +00:00
|
|
|
u32 state = StackCheck_GetState(iter);
|
2020-03-22 21:19:43 +00:00
|
|
|
if (state != STACK_STATUS_OK) {
|
2020-03-17 04:31:30 +00:00
|
|
|
ret = 1;
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
u32 StackCheck_Check(StackEntry* entry) {
|
2021-02-14 00:49:40 +00:00
|
|
|
if (entry == NULL) {
|
2020-03-17 04:31:30 +00:00
|
|
|
return StackCheck_CheckAll();
|
2020-03-22 21:19:43 +00:00
|
|
|
} else {
|
2020-03-17 04:31:30 +00:00
|
|
|
return StackCheck_GetState(entry);
|
2020-03-22 21:19:43 +00:00
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
}
|