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.
This commit is contained in:
Ville Juven 2022-12-22 10:12:22 +02:00 committed by Xiang Xiao
parent 069fac1c67
commit b0b352f784
1 changed files with 72 additions and 19 deletions

View File

@ -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 */