From b0b352f78487e1e5a4d3742be91995a2a4e9fb97 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Thu, 22 Dec 2022 10:12:22 +0200 Subject: [PATCH] sched/assert: Fix printing argv when address environments are in use Instantiate the correct address environment when reading the process's argument vector. Otherwise doing this will crash the system every time, causing a recursive assert loop. Also try to do a bit of sanity checking before attempting to read the process's memory, it might be in a bad state in which case this will fail anyway. --- sched/misc/assert.c | 91 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 19 deletions(-) diff --git a/sched/misc/assert.c b/sched/misc/assert.c index de3d738620..1c51e04fd4 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -209,11 +209,80 @@ static void showstacks(void) #endif +/**************************************************************************** + * Name: get_argv_str + * + * Description: + * Safely read the contents of a task's argument vector, into a a safe + * buffer. + * + ****************************************************************************/ + +static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size) +{ +#ifdef CONFIG_ARCH_ADDRENV + save_addrenv_t oldenv; + bool saved = false; +#endif + + /* Perform sanity checks */ + + if (!tcb || !tcb->group || !tcb->group->tg_info) + { + /* Something is very wrong -> get out */ + + *args = '\0'; + return; + } + +#ifdef CONFIG_ARCH_ADDRENV + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) + { + if ((tcb->group->tg_flags & GROUP_FLAG_ADDRENV) == 0) + { + /* Process should have address environment, but doesn't */ + + *args = '\0'; + return; + } + + up_addrenv_select(&tcb->group->tg_addrenv, &oldenv); + saved = true; + } +#endif + +#ifndef CONFIG_DISABLE_PTHREAD + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) + { + FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s *)tcb; + + snprintf(args, size, " %p %p", ptcb->cmn.entry.main, ptcb->arg); + } + else +#endif + { + FAR char **argv = tcb->group->tg_info->argv + 1; + size_t npos = 0; + + while (*argv != NULL && npos < size) + { + npos += snprintf(args + npos, size - npos, " %s", *argv++); + } + } + +#ifdef CONFIG_ARCH_ADDRENV + if (saved) + { + up_addrenv_restore(&oldenv); + } +#endif +} + /**************************************************************************** * Name: dump_task ****************************************************************************/ -static void dump_task(struct tcb_s *tcb, void *arg) +static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) { char args[64] = ""; #ifdef CONFIG_STACK_COLORATION @@ -246,25 +315,9 @@ static void dump_task(struct tcb_s *tcb, void *arg) } #endif -#ifndef CONFIG_DISABLE_PTHREAD - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; + /* Stringify the argument vector */ - snprintf(args, sizeof(args), " %p %p", - ptcb->cmn.entry.main, ptcb->arg); - } - else -#endif - { - char **argv = tcb->group->tg_info->argv + 1; - size_t npos = 0; - - while (*argv != NULL && npos < sizeof(args)) - { - npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); - } - } + get_argv_str(tcb, args, sizeof(args)); /* Dump interesting properties of this task */