提交 0fb49d44 编写于 作者: Z zhushengle

fix: 修复risc-v异常时,异常信息混乱且backtrace无法输出的问题

1.修复risc-v backtrace无法输出的问题
异常时未将fp传入,且backtrace校验不足,容易导致再次异常
2.优化task 输出信息格式
3.shell中task命令代码重复
4.OSBackTraceInit 拼写有误

Close #I4BPHX:riscv32_virt 异常时无法输出backtrace信息
Signed-off-by: Nzhushengle <zhushengle@huawei.com>
Change-Id: I141d5e7808fc967d846f425422f5dcf2ac01d1d1
上级 8dfcf712
......@@ -193,12 +193,10 @@ STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
return pc;
}
#elif (LOSCFG_BACKTRACE_TYPE == 2)
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
#define OS_BACKTRACE_START 1
#define OS_RA_OFFSET 4
#define OS_FP_OFFSET 8
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0)
#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value))
STATIC INLINE UINTPTR OsFpGet(VOID)
{
......@@ -208,12 +206,41 @@ STATIC INLINE UINTPTR OsFpGet(VOID)
return fp;
}
WEAK BOOL IsValidFP(UINTPTR fp)
{
LosTaskCB *taskCB = NULL;
UINTPTR stackTop, stackBottom;
UINTPTR irqStackTop, irqStackBottom;
if ((fp == FP_INIT_VALUE) || !OS_FP_ALIGN(fp)) {
return FALSE;
}
if (LOS_TaskIsRunning()) {
taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
stackTop = taskCB->topOfStack;
stackBottom = taskCB->topOfStack + taskCB->stackSize;
irqStackTop = (UINTPTR)CSTACK_START_ADDR;
irqStackBottom = (UINTPTR)CSTACK_SECTION_END;
} else {
stackTop = 0;
stackBottom = 0;
irqStackTop = (UINTPTR)CSTACK_START_ADDR;
irqStackBottom = (UINTPTR)CSTACK_SECTION_END;
}
if (((fp > stackTop) && (fp <= stackBottom)) || ((fp > irqStackTop) && (fp <= irqStackBottom))) {
return TRUE;
}
return FALSE;
}
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
UNUSED(SP);
UINT32 backFp = OsFpGet();
UINT32 tmpFp;
UINT32 backRa;
UINTPTR backFp;
UINTPTR tmpFp;
UINTPTR backRa;
UINT32 count = 0;
UINT32 index = 0;
......@@ -221,21 +248,31 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
return;
}
while (OS_FP_CHECK(backFp)) {
if (SP != 0) {
backFp = SP;
} else {
backFp = OsFpGet();
}
if (!IsValidFP(backFp)) {
PRINT_ERR("BackTrace failed! Invalid fp 0x%x\n", backFp);
return;
}
do {
tmpFp = backFp;
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
backRa = *((UINTPTR *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
backFp = *((UINTPTR *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
if (index++ < jumpCount) {
continue;
}
LR[count] = backRa;
count++;
if ((count == LRSize) || (backFp == tmpFp) ||
(!OsStackDataIsCodeAddr(backRa))) {
if ((count == LRSize) || (backFp == tmpFp)) {
break;
}
}
} while (IsValidFP(backFp));
if (count < LRSize) {
LR[count] = 0;
......@@ -737,7 +774,7 @@ VOID LOS_BackTrace(VOID)
PRINTK("----- traceback end -----\r\n");
}
VOID OSBackTraceInit(VOID)
VOID OsBackTraceInit(VOID)
{
OsBackTraceHookSet(LOS_RecordLR);
}
......
......@@ -216,7 +216,7 @@ extern CHAR *CSTACK_SECTION_END;
/* This function is currently used to register the memory leak check hook,
other uses do not need to be called temporarily. */
VOID OSBackTraceInit(VOID);
VOID OsBackTraceInit(VOID);
/* This function is used to print the function call stack. */
VOID LOS_BackTrace(VOID);
......
......@@ -30,116 +30,15 @@
*/
#include "stdlib.h"
#include "los_config.h"
#include "los_task.h"
#include "los_sem.h"
#include "shcmd.h"
#include "shell.h"
#define OS_INVALID_SEM_ID 0xFFFFFFFF
#define OS_ALL_TASK_MASK 0xFFFFFFFF
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitle(VOID)
{
PRINTK("Name TaskEntryAddr TID ");
PRINTK("Priority Status "
#if (LOSCFG_TASK_MEM_USED == 1)
"AllocSize "
#endif
"StackSize StackPoint TopOfStack");
PRINTK("\n");
PRINTK("---- ------------- --- ");
PRINTK("-------- -------- "
#if (LOSCFG_TASK_MEM_USED == 1)
"--------- "
#endif
"--------- ---------- ----------");
PRINTK("\n");
}
LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsGetSemID(const LosTaskCB *taskCB)
{
UINT32 semId = OS_INVALID_SEM_ID;
if (taskCB->taskSem != NULL) {
semId = ((LosSemCB *)taskCB->taskSem)->semID;
}
return semId;
}
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTaskArray)
{
const LosTaskCB *taskCB = NULL;
UINT32 loop;
UINT32 semId;
#if (LOSCFG_TASK_MEM_USED == 1)
UINT32 arraySize = sizeof(UINT32) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1);
UINT32 *getUsedSizeArray = (UINT32 *)LOS_MemAlloc(m_aucSysMem0, arraySize);
if (getUsedSizeArray == NULL) {
PRINTK("Memory is not enough to save task info!\n");
return;
}
(VOID)memset_s(getUsedSizeArray, arraySize, 0, arraySize);
OsTaskMemUsed(m_aucSysMem0, getUsedSizeArray, (LOSCFG_BASE_CORE_TSK_LIMIT + 1));
#endif
for (loop = 0; loop < g_taskMaxNum; ++loop) {
taskCB = allTaskArray + loop;
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
continue;
}
semId = OsGetSemID(taskCB);
PRINTK("%-23s%-20p0x%-5x", taskCB->taskName, taskCB->taskEntry, taskCB->taskID);
#if (LOSCFG_TASK_MEM_USED == 1)
PRINTK("%-11u%-13s0x%-11x 0x%-11x 0x%-8x 0x%-10x ", taskCB->priority,
OsConvertTskStatus(taskCB->taskStatus), getUsedSizeArray[loop], taskCB->stackSize,
taskCB->stackPointer, taskCB->topOfStack, semId);
#else
PRINTK("%-11u%-13s0x%-11x 0x%-8x 0x%-10x ", taskCB->priority,
OsConvertTskStatus(taskCB->taskStatus), taskCB->stackSize,
taskCB->stackPointer, taskCB->topOfStack, semId);
#endif
PRINTK("\n");
}
#if (LOSCFG_TASK_MEM_USED == 1)
(VOID)LOS_MemFree(m_aucSysMem0, getUsedSizeArray);
#endif
}
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskId)
{
BOOL backupFlag = TRUE;
UINT32 size;
LosTaskCB *tcbArray = NULL;
INT32 ret;
if (taskId == OS_ALL_TASK_MASK) {
size = g_taskMaxNum * sizeof(LosTaskCB);
tcbArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);
if (tcbArray == NULL) {
PRINTK("Memory is not enough to save task info!\n");
tcbArray = g_taskCBArray;
backupFlag = FALSE;
}
if (backupFlag == TRUE) {
ret = memcpy_s(tcbArray, size, g_taskCBArray, size);
if (ret != 0) {
return LOS_NOK;
}
}
OsShellCmdTskInfoTitle();
OsShellCmdTskInfoData(tcbArray);
if (backupFlag == TRUE) {
(VOID)LOS_MemFree(m_aucSysMem0, tcbArray);
}
OsGetAllTskInfo();
}
return LOS_OK;
......
......@@ -218,41 +218,21 @@ LITE_OS_SEC_TEXT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum)
return LOS_OK;
}
STATIC VOID DisplayTaskInfo(VOID)
STATIC VOID ExcBackTrace(UINTPTR fp)
{
TSK_INFO_S taskInfo;
UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = { 0 };
UINT32 index;
UINT32 ret;
PRINTK("ID Pri Status name \n\r");
PRINTK("-- --- --------- ----\n\r");
OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, fp);
for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) {
ret = LOS_TaskInfoGet(index, &taskInfo);
if (ret != LOS_OK) {
continue;
}
PRINTK("%d %d %s %s \n\r",
taskInfo.uwTaskID, taskInfo.usTaskPrio, OsConvertTskStatus(taskInfo.usTaskStatus), taskInfo.acName);
}
return;
}
STATIC VOID ExcBackTrace(VOID)
{
UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0};
UINT32 index;
OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 1, 0); /* 1: Ignore the one layer call relationship within the function. */
PRINTK("----- traceback start -----\r\n");
PRINTK("----- traceback start -----\n");
for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
if (LR[index] == 0) {
break;
}
PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]);
PRINTK("traceback %d -- lr = 0x%x\n", index, LR[index]);
}
PRINTK("----- traceback end -----\r\n");
PRINTK("----- traceback end -----\n");
}
STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc)
......@@ -295,29 +275,33 @@ STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc)
PRINTK("t5 = 0x%x\n", taskContext->t5);
PRINTK("t6 = 0x%x\n", taskContext->t6);
ExcBackTrace();
ExcBackTrace(taskContext->s0);
}
STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr)
{
PRINTK("\r\nException Information \n\r");
PRINTK("\nException Information \n");
if (g_excInfo.type < RISCV_EXC_TYPE_NUM) {
PRINTK("Exc type : Oops - %s\n\r", g_excInformation[g_excInfo.type]);
PRINTK("Exc type : Oops - %s\n", g_excInformation[g_excInfo.type]);
} else {
PRINTK("Exc type : Oops - Invalid\n\r");
PRINTK("Exc type : Oops - Invalid\n");
}
PRINTK("taskName = %s\n\r", g_losTask.runTask->taskName);
PRINTK("taskID = %u\n\r", g_losTask.runTask->taskID);
PRINTK("system mem addr:0x%x\n\r", (UINTPTR)LOSCFG_SYS_HEAP_ADDR);
if (LOS_TaskIsRunning()) {
PRINTK("taskName = %s\n", g_losTask.runTask->taskName);
PRINTK("taskID = %u\n", g_losTask.runTask->taskID);
} else {
PRINTK("The exception occurs during system startup!\n");
}
PRINTK("system mem addr:0x%x\n", (UINTPTR)LOSCFG_SYS_HEAP_ADDR);
ExcInfoDisplayContext(&g_excInfo);
}
WEAK UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp)
{
/* Unaligned access fixes are not supported by default */
PRINTK("Unaligned access fixes are not supported by default!\n\r");
PRINTK("Unaligned access fixes are not supported by default!\n");
return LOS_NOK;
}
......@@ -327,7 +311,7 @@ VOID HalExcEntry(const LosExcContext *excBufAddr)
g_excInfo.type = excBufAddr->mcause & 0x1FF;
g_excInfo.context = (LosExcContext *)excBufAddr;
if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */
PRINTK("hard fault!\n\r");
PRINTK("hard fault!\n");
goto SYSTEM_DEATH;
}
......@@ -342,8 +326,10 @@ VOID HalExcEntry(const LosExcContext *excBufAddr)
ExcInfoDisplay(excBufAddr);
PRINTK("----------------All Task infomation ------------\n\r");
DisplayTaskInfo();
if (LOS_TaskIsRunning()) {
PRINTK("----------------All Task infomation ------------\n");
OsGetAllTskInfo();
}
SYSTEM_DEATH:
OsDoExcHook(EXC_INTERRUPT);
......
......@@ -483,7 +483,7 @@ extern UINT8 *m_aucSysMem0;
* Configuration memory leak detection
* @attention
* Need to enable backtrace module synchronously by configuration LOSCFG_BACKTRACE_TYPE,
* and call OSBackTraceInit to complete initialization before the memory pool is initialized.
* and call OsBackTraceInit to complete initialization before the memory pool is initialized.
*/
#ifndef LOSCFG_MEM_LEAKCHECK
#define LOSCFG_MEM_LEAKCHECK 0
......
......@@ -121,7 +121,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)
PRINTK("entering kernel init...\n");
#if (LOSCFG_BACKTRACE_TYPE != 0)
OSBackTraceInit();
OsBackTraceInit();
#endif
OsRegister();
......
......@@ -288,18 +288,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskCpupInfo(CPUP_INFO_S **cpuLessOneSec,
LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader()
{
PRINTK("\r\nTID Priority Status "
"StackSize WaterLine StackPoint TopOfStack EventMask SemID");
PRINTK("\r\n TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID");
#if (LOSCFG_BASE_CORE_CPUP == 1)
PRINTK(" CPUUSE CPUUSE10s CPUUSE1s ");
#endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK(" name\n");
PRINTK("--- -------- -------- ");
PRINTK("--------- ---------- ---------- ---------- --------- -----");
PRINTK("name\n");
PRINTK(" --- -------- -------- ");
PRINTK("--------- --------- ---------- ---------- --------- ------ ");
#if (LOSCFG_BASE_CORE_CPUP == 1)
PRINTK(" ------- --------- ---------");
PRINTK("------- --------- -------- ");
#endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK(" ----\n");
PRINTK("----\n");
}
/*****************************************************************************
......@@ -335,16 +334,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID)
continue;
}
PRINTK("%d %d %s 0x%x 0x%x 0x%x 0x%x 0x%x ",
semID = (taskCB->taskSem == NULL) ? OS_NULL_SHORT : (((LosSemCB *)taskCB->taskSem)->semID);
PRINTK("%4u%9u%10s%#10x%#10x%#11x%#11x%#10x%#7x",
taskCB->taskID, taskCB->priority, OsConvertTskStatus(taskCB->taskStatus),
taskCB->stackSize, OsGetTaskWaterLine(taskCB->taskID),
(UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask);
semID = (taskCB->taskSem == NULL) ? OS_NULL_SHORT : (((LosSemCB *)taskCB->taskSem)->semID);
PRINTK("0x%x ", semID);
(UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask, semID);
#if (LOSCFG_BASE_CORE_CPUP == 1)
PRINTK("%d.%d %d.%d %d.%d ",
PRINTK("%6u.%-2u%7u.%-2u%6u.%-2u ",
cpuLessOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
cpuLessOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT,
cpuTenSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
......@@ -352,7 +349,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID)
cpuOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
cpuOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT);
#endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK("%s\n", taskCB->taskName);
PRINTK("%-32s\n", taskCB->taskName);
}
#if (LOSCFG_BASE_CORE_CPUP == 1)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册