binfmt/elf: treat nx_priority == 0 as "use the default"

apps/Application.mk stamps each program's configured priority into its ELF
as an absolute nx_priority symbol, and encodes PRIORITY =
SCHED_PRIORITY_DEFAULT as zero:

  SYM_PRIORITY = $(if $(filter SCHED_PRIORITY_DEFAULT,$(PRIORITY_$@)),0,\
                   $(PRIORITY_$@))

elf_loadbinary() took that literally, so any program whose Makefile
declares SCHED_PRIORITY_DEFAULT -- testing/ostest, among others -- was
created at priority 0.  That ties with the idle task, and the new task is
queued behind it, so it never runs.

The failure gives nothing to go on: the loader reports success, the task
appears in the task list as READY-TO-RUN, and the program never executes
an instruction.  Found on an ESP32-S3 BUILD_KERNEL target where ostest
loaded and then sat with sched_priority=0 behind Idle_Task in
g_readytorun across repeated JTAG samples, while programs with explicit
numeric priorities (nsh=100, getprime=50) ran normally.

Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marco Casaroli 2026-07-25 20:39:46 +02:00
parent 216edd74db
commit a85f2dfa1b

View file

@ -184,8 +184,19 @@ static int elf_loadbinary(FAR struct binary_s *binp,
binp->stacksize = CONFIG_ELF_STACKSIZE;
}
/* A zero nx_priority means "use the default", not "priority zero". That
* is how apps/Application.mk encodes PRIORITY = SCHED_PRIORITY_DEFAULT:
*
* SYM_PRIORITY = $(if $(filter SCHED_PRIORITY_DEFAULT,\
* $(PRIORITY_$@)),0,$(PRIORITY_$@))
*
* Taking it literally gives the task the idle task's priority, so it is
* queued behind the idle task and never runs -- the program loads, reports
* no error, and simply never executes an instruction.
*/
ret = libelf_findsymbol(&loadinfo, "nx_priority", &sym);
if (ret == 0)
if (ret == 0 && sym.st_value != 0)
{
binp->priority = sym.st_value;
}