提交 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) ...@@ -193,12 +193,10 @@ STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
return pc; return pc;
} }
#elif (LOSCFG_BACKTRACE_TYPE == 2) #elif (LOSCFG_BACKTRACE_TYPE == 2)
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
#define OS_BACKTRACE_START 1 #define OS_BACKTRACE_START 1
#define OS_RA_OFFSET 4 #define OS_RA_OFFSET 4
#define OS_FP_OFFSET 8 #define OS_FP_OFFSET 8
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0) #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) STATIC INLINE UINTPTR OsFpGet(VOID)
{ {
...@@ -208,12 +206,41 @@ STATIC INLINE UINTPTR OsFpGet(VOID) ...@@ -208,12 +206,41 @@ STATIC INLINE UINTPTR OsFpGet(VOID)
return fp; 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) VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{ {
UNUSED(SP); UINTPTR backFp;
UINT32 backFp = OsFpGet(); UINTPTR tmpFp;
UINT32 tmpFp; UINTPTR backRa;
UINT32 backRa;
UINT32 count = 0; UINT32 count = 0;
UINT32 index = 0; UINT32 index = 0;
...@@ -221,21 +248,31 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP) ...@@ -221,21 +248,31 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
return; 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; tmpFp = backFp;
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET)); backRa = *((UINTPTR *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET)); backFp = *((UINTPTR *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
if (index++ < jumpCount) { if (index++ < jumpCount) {
continue; continue;
} }
LR[count] = backRa; LR[count] = backRa;
count++; count++;
if ((count == LRSize) || (backFp == tmpFp) || if ((count == LRSize) || (backFp == tmpFp)) {
(!OsStackDataIsCodeAddr(backRa))) {
break; break;
} }
} } while (IsValidFP(backFp));
if (count < LRSize) { if (count < LRSize) {
LR[count] = 0; LR[count] = 0;
...@@ -737,7 +774,7 @@ VOID LOS_BackTrace(VOID) ...@@ -737,7 +774,7 @@ VOID LOS_BackTrace(VOID)
PRINTK("----- traceback end -----\r\n"); PRINTK("----- traceback end -----\r\n");
} }
VOID OSBackTraceInit(VOID) VOID OsBackTraceInit(VOID)
{ {
OsBackTraceHookSet(LOS_RecordLR); OsBackTraceHookSet(LOS_RecordLR);
} }
......
...@@ -216,7 +216,7 @@ extern CHAR *CSTACK_SECTION_END; ...@@ -216,7 +216,7 @@ extern CHAR *CSTACK_SECTION_END;
/* This function is currently used to register the memory leak check hook, /* This function is currently used to register the memory leak check hook,
other uses do not need to be called temporarily. */ 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. */ /* This function is used to print the function call stack. */
VOID LOS_BackTrace(VOID); VOID LOS_BackTrace(VOID);
......
...@@ -30,116 +30,15 @@ ...@@ -30,116 +30,15 @@
*/ */
#include "stdlib.h" #include "stdlib.h"
#include "los_config.h"
#include "los_task.h" #include "los_task.h"
#include "los_sem.h"
#include "shcmd.h" #include "shcmd.h"
#include "shell.h" #include "shell.h"
#define OS_ALL_TASK_MASK 0xFFFFFFFF
#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) 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) { if (taskId == OS_ALL_TASK_MASK) {
size = g_taskMaxNum * sizeof(LosTaskCB); OsGetAllTskInfo();
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);
}
} }
return LOS_OK; return LOS_OK;
......
...@@ -218,41 +218,21 @@ LITE_OS_SEC_TEXT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) ...@@ -218,41 +218,21 @@ LITE_OS_SEC_TEXT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum)
return LOS_OK; 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 index;
UINT32 ret;
PRINTK("ID Pri Status name \n\r");
PRINTK("-- --- --------- ----\n\r");
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) OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, fp);
{
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++) { for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
if (LR[index] == 0) { if (LR[index] == 0) {
break; 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) STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc)
...@@ -295,29 +275,33 @@ STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc) ...@@ -295,29 +275,33 @@ STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc)
PRINTK("t5 = 0x%x\n", taskContext->t5); PRINTK("t5 = 0x%x\n", taskContext->t5);
PRINTK("t6 = 0x%x\n", taskContext->t6); PRINTK("t6 = 0x%x\n", taskContext->t6);
ExcBackTrace(); ExcBackTrace(taskContext->s0);
} }
STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr) STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr)
{ {
PRINTK("\r\nException Information \n\r"); PRINTK("\nException Information \n");
if (g_excInfo.type < RISCV_EXC_TYPE_NUM) { 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 { } else {
PRINTK("Exc type : Oops - Invalid\n\r"); PRINTK("Exc type : Oops - Invalid\n");
} }
PRINTK("taskName = %s\n\r", g_losTask.runTask->taskName); if (LOS_TaskIsRunning()) {
PRINTK("taskID = %u\n\r", g_losTask.runTask->taskID); PRINTK("taskName = %s\n", g_losTask.runTask->taskName);
PRINTK("system mem addr:0x%x\n\r", (UINTPTR)LOSCFG_SYS_HEAP_ADDR); 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); ExcInfoDisplayContext(&g_excInfo);
} }
WEAK UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp) WEAK UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp)
{ {
/* Unaligned access fixes are not supported by default */ /* 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; return LOS_NOK;
} }
...@@ -327,7 +311,7 @@ VOID HalExcEntry(const LosExcContext *excBufAddr) ...@@ -327,7 +311,7 @@ VOID HalExcEntry(const LosExcContext *excBufAddr)
g_excInfo.type = excBufAddr->mcause & 0x1FF; g_excInfo.type = excBufAddr->mcause & 0x1FF;
g_excInfo.context = (LosExcContext *)excBufAddr; g_excInfo.context = (LosExcContext *)excBufAddr;
if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */ if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */
PRINTK("hard fault!\n\r"); PRINTK("hard fault!\n");
goto SYSTEM_DEATH; goto SYSTEM_DEATH;
} }
...@@ -342,8 +326,10 @@ VOID HalExcEntry(const LosExcContext *excBufAddr) ...@@ -342,8 +326,10 @@ VOID HalExcEntry(const LosExcContext *excBufAddr)
ExcInfoDisplay(excBufAddr); ExcInfoDisplay(excBufAddr);
PRINTK("----------------All Task infomation ------------\n\r"); if (LOS_TaskIsRunning()) {
DisplayTaskInfo(); PRINTK("----------------All Task infomation ------------\n");
OsGetAllTskInfo();
}
SYSTEM_DEATH: SYSTEM_DEATH:
OsDoExcHook(EXC_INTERRUPT); OsDoExcHook(EXC_INTERRUPT);
......
...@@ -483,7 +483,7 @@ extern UINT8 *m_aucSysMem0; ...@@ -483,7 +483,7 @@ extern UINT8 *m_aucSysMem0;
* Configuration memory leak detection * Configuration memory leak detection
* @attention * @attention
* Need to enable backtrace module synchronously by configuration LOSCFG_BACKTRACE_TYPE, * 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 #ifndef LOSCFG_MEM_LEAKCHECK
#define LOSCFG_MEM_LEAKCHECK 0 #define LOSCFG_MEM_LEAKCHECK 0
......
...@@ -121,7 +121,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID) ...@@ -121,7 +121,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)
PRINTK("entering kernel init...\n"); PRINTK("entering kernel init...\n");
#if (LOSCFG_BACKTRACE_TYPE != 0) #if (LOSCFG_BACKTRACE_TYPE != 0)
OSBackTraceInit(); OsBackTraceInit();
#endif #endif
OsRegister(); OsRegister();
......
...@@ -288,18 +288,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskCpupInfo(CPUP_INFO_S **cpuLessOneSec, ...@@ -288,18 +288,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskCpupInfo(CPUP_INFO_S **cpuLessOneSec,
LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader() LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader()
{ {
PRINTK("\r\nTID Priority Status " PRINTK("\r\n TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID");
"StackSize WaterLine StackPoint TopOfStack EventMask SemID");
#if (LOSCFG_BASE_CORE_CPUP == 1) #if (LOSCFG_BASE_CORE_CPUP == 1)
PRINTK(" CPUUSE CPUUSE10s CPUUSE1s "); PRINTK(" CPUUSE CPUUSE10s CPUUSE1s ");
#endif /* LOSCFG_BASE_CORE_CPUP */ #endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK(" name\n"); PRINTK("name\n");
PRINTK("--- -------- -------- "); PRINTK(" --- -------- -------- ");
PRINTK("--------- ---------- ---------- ---------- --------- -----"); PRINTK("--------- --------- ---------- ---------- --------- ------ ");
#if (LOSCFG_BASE_CORE_CPUP == 1) #if (LOSCFG_BASE_CORE_CPUP == 1)
PRINTK(" ------- --------- ---------"); PRINTK("------- --------- -------- ");
#endif /* LOSCFG_BASE_CORE_CPUP */ #endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK(" ----\n"); PRINTK("----\n");
} }
/***************************************************************************** /*****************************************************************************
...@@ -335,16 +334,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID) ...@@ -335,16 +334,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID)
continue; 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->taskID, taskCB->priority, OsConvertTskStatus(taskCB->taskStatus),
taskCB->stackSize, OsGetTaskWaterLine(taskCB->taskID), taskCB->stackSize, OsGetTaskWaterLine(taskCB->taskID),
(UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask); (UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask, semID);
semID = (taskCB->taskSem == NULL) ? OS_NULL_SHORT : (((LosSemCB *)taskCB->taskSem)->semID);
PRINTK("0x%x ", semID);
#if (LOSCFG_BASE_CORE_CPUP == 1) #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,
cpuLessOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT, cpuLessOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT,
cpuTenSec[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) ...@@ -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,
cpuOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT); cpuOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT);
#endif /* LOSCFG_BASE_CORE_CPUP */ #endif /* LOSCFG_BASE_CORE_CPUP */
PRINTK("%s\n", taskCB->taskName); PRINTK("%-32s\n", taskCB->taskName);
} }
#if (LOSCFG_BASE_CORE_CPUP == 1) #if (LOSCFG_BASE_CORE_CPUP == 1)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册