From 323790607240034d544b01661efc5d5f10e8d0e1 Mon Sep 17 00:00:00 2001 From: ritesh55555 Date: Wed, 8 Jan 2025 17:04:51 +0530 Subject: [PATCH] kernel/sched: fix logging after stack overflow - This commit changes logging method from dbg to lldbg to print stack overflow information. This is done because after stack overflow, using dbg does not work because of more stack memory requirement. But in the lldbg case, it uses low level syslog, so it uses minimal stack memory. --- os/kernel/sched/Make.defs | 4 ++ os/kernel/sched/sched.h | 4 ++ os/kernel/sched/sched_addreadytorun.c | 18 +---- os/kernel/sched/sched_checkstackoverflow.c | 83 ++++++++++++++++++++++ os/kernel/sched/sched_removereadytorun.c | 20 ++---- 5 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 os/kernel/sched/sched_checkstackoverflow.c diff --git a/os/kernel/sched/Make.defs b/os/kernel/sched/Make.defs index 4f21f4b518..af9fde591d 100644 --- a/os/kernel/sched/Make.defs +++ b/os/kernel/sched/Make.defs @@ -62,6 +62,10 @@ CSRCS += sched_lock.c sched_unlock.c sched_lockcount.c sched_self.c CSRCS += sched_getaffinity.c sched_setaffinity.c CSRCS += sched_getcpu.c +ifeq ($(CONFIG_SW_STACK_OVERFLOW_DETECTION),y) +CSRCS += sched_checkstackoverflow.c +endif + ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sched_reprioritize.c endif diff --git a/os/kernel/sched/sched.h b/os/kernel/sched/sched.h index f20d439d58..9cb1589d91 100644 --- a/os/kernel/sched/sched.h +++ b/os/kernel/sched/sched.h @@ -358,6 +358,10 @@ void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state); void sched_removeblocked(FAR struct tcb_s *btcb); int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority); +#ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION +void sched_checkstackoverflow(FAR struct tcb_s *rtcb); +#endif + #ifdef CONFIG_PRIORITY_INHERITANCE int sched_reprioritize(FAR struct tcb_s *tcb, int sched_priority); #else diff --git a/os/kernel/sched/sched_addreadytorun.c b/os/kernel/sched/sched_addreadytorun.c index 15547d21ba..a133be8670 100644 --- a/os/kernel/sched/sched_addreadytorun.c +++ b/os/kernel/sched/sched_addreadytorun.c @@ -124,14 +124,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) bool ret; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif /* Check if pre-emption is disabled for the current running task and if * the new ready-to-run task would cause the current running task to be @@ -182,14 +175,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) int cpu; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif /* Check if the blocked TCB is locked to this CPU */ diff --git a/os/kernel/sched/sched_checkstackoverflow.c b/os/kernel/sched/sched_checkstackoverflow.c new file mode 100644 index 0000000000..b682800266 --- /dev/null +++ b/os/kernel/sched/sched_checkstackoverflow.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * + * Copyright 2025 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_checkstackoverflow + * + * Description: + * This function checks stack overflow condition for a thread. + * + * Inputs: + * rtcb - Points to the TCB that is ready-to-run + * + ****************************************************************************/ + +void sched_checkstackoverflow(FAR struct tcb_s *rtcb) +{ + irqstate_t flags = enter_critical_section(); + + if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { + lldbg_noarg("\n############### STACK OVERFLOW at pid %d ", rtcb->pid); +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg_noarg("(%s) ", rtcb->name); +#endif + lldbg_noarg("###################\n"); + PANIC(); + } + + leave_critical_section(flags); +} diff --git a/os/kernel/sched/sched_removereadytorun.c b/os/kernel/sched/sched_removereadytorun.c index 0b3dfd3cc4..363473690d 100644 --- a/os/kernel/sched/sched_removereadytorun.c +++ b/os/kernel/sched/sched_removereadytorun.c @@ -116,15 +116,9 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) bool ret = false; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif + /* Check if the TCB to be removed is at the head of the ready to run list. * In this case, we are removing the currently active task. */ @@ -157,15 +151,9 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) int cpu; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif + /* Which CPU (if any) is the task running on? Which task list holds * the TCB */