diff --git a/Kconfig b/Kconfig index 3f9e10a9..d1116bea 100644 --- a/Kconfig +++ b/Kconfig @@ -554,6 +554,13 @@ config SHELL_CMD_DEBUG default n depends on DEBUG_VERSION && SHELL +config DEBUG_TOOLS + bool "Enable DEBUG TOOLS" + default n + depends on DEBUG_VERSION + help + Answer Y to enable LiteOS debug tools, include stackdump, hwidump, tasktrack. + config USB_DEBUG bool "Enable USB Debug" default n diff --git a/arch/include/los_arch.h b/arch/include/los_arch.h index 193b7fa6..258ab024 100644 --- a/arch/include/los_arch.h +++ b/arch/include/los_arch.h @@ -41,6 +41,52 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +#if defined(__ICCARM__) || defined(__CC_ARM) +STATIC INLINE UINTPTR ArchSpGet(VOID) +{ + UINTPTR sp; + __asm("mov %0, sp" : "=r" (sp)); + return sp; +} + +STATIC INLINE UINTPTR ArchPspGet(VOID) +{ + UINTPTR psp; + __asm("mrs %0, psp" : "=r" (psp)); + return psp; +} + +STATIC INLINE UINTPTR ArchMspGet(VOID) +{ + UINTPTR msp; + __asm("mrs %0, msp" : "=r" (msp)); + return msp; +} +#elif defined(__CLANG_ARM) || defined(__GNUC__) +STATIC INLINE UINTPTR ArchSpGet(VOID) +{ + UINTPTR sp; + __asm volatile("mov %0, sp" : "=r" (sp)); + return sp; +} + +STATIC INLINE UINTPTR ArchPspGet(VOID) +{ + UINTPTR psp; + __asm volatile("mrs %0, psp" : "=r" (psp)); + return psp; +} + +STATIC INLINE UINTPTR ArchMspGet(VOID) +{ + UINTPTR msp; + __asm volatile("mrs %0, msp" : "=r" (msp)); + return msp; +} +#else +/* Other platforms to be improved */ +#endif + VOID ArchInit(VOID); #ifdef __cplusplus diff --git a/components/BUILD.gn b/components/BUILD.gn index 513e77a8..20c540f6 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn @@ -34,6 +34,7 @@ group("components") { "backtrace", "cppsupport", "cpup", + "debugtools", "dynlink", "exchook", "fs", @@ -64,5 +65,6 @@ config("public") { "lmk:public", "lms:public", "signal:public", + "debugtools:public", ] } diff --git a/components/backtrace/los_backtrace.c b/components/backtrace/los_backtrace.c index 0462c2d0..9c1ecfda 100644 --- a/components/backtrace/los_backtrace.c +++ b/components/backtrace/los_backtrace.c @@ -32,6 +32,7 @@ #include "los_backtrace.h" #include "los_task.h" #include "los_debug.h" +#include "los_arch.h" #if (LOSCFG_BACKTRACE_TYPE == 4) #include "los_arch_regs.h" #endif @@ -60,52 +61,6 @@ WEAK BOOL OsStackDataIsCodeAddr(UINTPTR value) #define OS_BLX_INX_MASK 0xFF00 #define OS_BLX_INX 0x4700 -#if defined(__ICCARM__) || defined(__CC_ARM) -STATIC INLINE UINTPTR HalSpGet(VOID) -{ - UINTPTR sp; - __asm("mov %0, sp" : "=r" (sp)); - return sp; -} - -STATIC INLINE UINTPTR HalPspGet(VOID) -{ - UINTPTR psp; - __asm("mrs %0, psp" : "=r" (psp)); - return psp; -} - -STATIC INLINE UINTPTR HalMspGet(VOID) -{ - UINTPTR msp; - __asm("mrs %0, msp" : "=r" (msp)); - return msp; -} -#elif defined(__CLANG_ARM) || defined(__GNUC__) -STATIC INLINE UINTPTR HalSpGet(VOID) -{ - UINTPTR sp; - __asm volatile("mov %0, sp" : "=r" (sp)); - return sp; -} - -STATIC INLINE UINTPTR HalPspGet(VOID) -{ - UINTPTR psp; - __asm volatile("mrs %0, psp" : "=r" (psp)); - return psp; -} - -STATIC INLINE UINTPTR HalMspGet(VOID) -{ - UINTPTR msp; - __asm volatile("mrs %0, msp" : "=r" (msp)); - return msp; -} -#else -#error Unknown compiler. -#endif - STATIC INLINE BOOL OsInsIsBlOrBlx(UINTPTR addr) { UINT16 ins1 = *((UINT16 *)addr); @@ -138,8 +93,8 @@ STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINT } } } else { - if (HalSpGet() != HalPspGet()) { - *stackStart = HalMspGet(); + if (ArchSpGet() != ArchPspGet()) { + *stackStart = ArchMspGet(); *stackEnd = CSTACK_END_ADDR; if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) { PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n", @@ -148,7 +103,7 @@ STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINT } PRINTK("msp, start = %x, end = %x\n", *stackStart, *stackEnd); } else { - *stackStart = HalPspGet(); + *stackStart = ArchPspGet(); UINT32 taskID = LOS_CurTaskIDGet(); LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); *stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize; diff --git a/components/debugtools/BUILD.gn b/components/debugtools/BUILD.gn new file mode 100755 index 00000000..74f520da --- /dev/null +++ b/components/debugtools/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_m/liteos.gni") + +module_switch = defined(LOSCFG_DEBUG_TOOLS) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_stackdump.c" ] + configs += [ "$LITEOSTOPDIR:warn_config" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/components/debugtools/los_debugtools.h b/components/debugtools/los_debugtools.h new file mode 100755 index 00000000..863bb832 --- /dev/null +++ b/components/debugtools/los_debugtools.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_DEBUGTOOLS_H +#define _LOS_DEBUGTOOLS_H + +#include "los_config.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define PRINT_PER_ROW 4 + +/* Shell Callback */ +extern UINT32 OsShellCmdStackDump(INT32 argc, const CHAR **argv); + +/* other module Callback */ + +/* External Interface */ +extern VOID LOS_TaskStackDump(UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/components/debugtools/los_stackdump.c b/components/debugtools/los_stackdump.c new file mode 100755 index 00000000..14b5a31a --- /dev/null +++ b/components/debugtools/los_stackdump.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_debugtools.h" +#include "securec.h" +#include "los_debug.h" +#include "los_memory.h" +#include "los_arch.h" + +#if (LOSCFG_DEBUG_TOOLS == 1) +typedef struct { + UINT32 waterLine; + UINT32 taskSPTop; + UINT32 taskSPLimit; + UINTPTR taskSP; +} DumpInfo; + +STATIC VOID ShowFormat(UINTPTR *buf, DumpInfo *info) +{ + INT32 i; + + UINT32 len = info->waterLine / sizeof(UINTPTR); + UINTPTR addr = (info->taskSPLimit - info->waterLine); + + for (i = 0; i < len; i++) { + if ((i % PRINT_PER_ROW) == 0) { + PRINTK("\r\n 0x%08x: ", addr); + } + if (addr == info->taskSP) { + PRINTK(" *%08x", buf[i]); + } else { + PRINTK(" %08x", buf[i]); + } + addr += sizeof(UINTPTR); + } + + PRINTK("\r\n"); +} + +STATIC INT32 DumpTaskInfo(UINT32 taskID, UINTPTR *buf, DumpInfo *info) +{ + errno_t ret; + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + + if (taskID == LOS_CurTaskIDGet()) { + info->taskSP = ArchSpGet(); + } else { + info->taskSP = (UINTPTR)taskCB->stackPointer; + } + + info->taskSPTop = taskCB->topOfStack; + info->taskSPLimit = taskCB->topOfStack + taskCB->stackSize; + if ((info->taskSP > info->taskSPLimit) || (info->taskSP < info->taskSPTop)) { + return LOS_NOK; + } + + ret = memcpy_s(buf, info->waterLine, (const VOID *)(info->taskSPLimit - info->waterLine), info->waterLine); + if (ret != EOK) { + return LOS_NOK; + } + + return LOS_OK; +} + +VOID LOS_TaskStackDump(UINT32 taskID) +{ + UINTPTR *buf = NULL; + DumpInfo info; + UINT32 intSave; + INT32 ret; + + if (taskID > g_taskMaxNum) { + PRINT_ERR("error taskID %u\r\n", taskID); + return; + } + + if (OS_INT_ACTIVE) { + PRINT_ERR("called during an interrupt.\r\n"); + return; + } + + intSave = LOS_IntLock(); + info.waterLine = OsGetTaskWaterLine(taskID); + if (info.waterLine == OS_NULL_INT) { + LOS_IntRestore(intSave); + return; + } + + buf = (UINTPTR *)LOS_MemAlloc(OS_SYS_MEM_ADDR, info.waterLine); + if (buf == NULL) { + LOS_IntRestore(intSave); + PRINT_ERR("alloc failed for dump\n"); + return; + } + (VOID)memset_s(buf, info.waterLine, 0, info.waterLine); + + ret = DumpTaskInfo(taskID, buf, &info); + if (ret != LOS_OK) { + LOS_IntRestore(intSave); + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, buf); + PRINT_ERR("SP 0x%x may error or memcpy_s failed, stack space from 0x%x to 0x%x\r\n", \ + info.taskSP, info.taskSPTop, info.taskSPLimit); + return; + } + + LOS_IntRestore(intSave); + PRINTK("Task %u, SP 0x%x, WaterLine 0x%x", taskID, info.taskSP, info.waterLine); + ShowFormat(buf, &info); + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, buf); + + return; +} + +UINT32 OsShellCmdStackDump(INT32 argc, const CHAR **argv) +{ + UINT32 taskID; + + if (argc != 1) { + PRINT_ERR("\nUsage: stack taskID\n"); + return LOS_NOK; + } + + taskID = (UINT32)atoi(argv[0]); + + LOS_TaskStackDump(taskID); + return LOS_OK; +} +#endif /* LOSCFG_STACK_DUMP == 1 */ diff --git a/components/shell/src/base/shcmd.c b/components/shell/src/base/shcmd.c index 0440ec70..4d30781d 100644 --- a/components/shell/src/base/shcmd.c +++ b/components/shell/src/base/shcmd.c @@ -39,6 +39,10 @@ #include "los_mux.h" #include "los_memory.h" +#if (LOSCFG_DEBUG_TOOLS == 1) +#include "los_debugtools.h" +#endif + #define SHELL_INIT_MAGIC_FLAG 0xABABABAB STATIC CmdModInfo cmdInfo; @@ -51,7 +55,7 @@ CmdItem g_shellcmdAll[] = { {CMD_TYPE_EX, "ifconfig", XARGS, (CmdCallBackFunc)lwip_ifconfig}, {CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)OsShellPing}, #endif -#if LOSCFG_FS_VFS +#if (LOSCFG_FS_VFS == 1) {CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)OsShellCmdTouch}, {CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)OsShellCmdLs}, {CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)OsShellCmdPwd}, @@ -62,7 +66,9 @@ CmdItem g_shellcmdAll[] = { {CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)OsShellCmdMkdir}, {CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)OsShellCmdCp}, #endif - +#if (LOSCFG_DEBUG_TOOLS == 1) + {CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsShellCmdStackDump}, +#endif {CMD_TYPE_EX, "help", 0, (CmdCallBackFunc)OsShellCmdHelp}, };