diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c index e90b6ef238..ee82f96561 100644 --- a/binfmt/nxflat.c +++ b/binfmt/nxflat.c @@ -246,18 +246,28 @@ static int nxflat_unloadbinary(FAR struct binary_s *binp) if (dspace != NULL) { - /* Free dspace region */ + /* Check if this is the last reference to dspace. It may still be + * needed by other threads. In that case, it must persist after this + * thread terminates. + */ - kumm_free(dspace->region); - dspace->region = 0; + if (dspace->crefs == 1) + { + /* Free the dspace region */ + + kumm_free(dspace->region); + dspace->region = NULL; + + /* Mark alloc[0] (dspace) as freed */ + + binp->alloc[0] = NULL; + + /* The reference count will be decremented to zero and the dspace + * container will be freed in sched/sched_releasetcb.c + */ + } } - /* Mark alloc[0] (dspace) as freed */ - - binp->alloc[0] = NULL; - - /* dspace container will be freed in sched/sched_releasetcb */ - return OK; } diff --git a/sched/sched/sched_releasetcb.c b/sched/sched/sched_releasetcb.c index 62e73a0caa..4c7ccceba3 100644 --- a/sched/sched/sched_releasetcb.c +++ b/sched/sched/sched_releasetcb.c @@ -168,7 +168,7 @@ int sched_releasetcb(FAR struct tcb_s *tcb, uint8_t ttype) #ifdef CONFIG_PIC /* Delete the task's allocated DSpace region (external modules only) */ - if (tcb->dspace) + if (tcb->dspace != NULL) { if (tcb->dspace->crefs <= 1) {