sched/waitpid: handle waitpid waitting tcb->group is NULL

Fail case:
exit -> nxtask_terminate -> nxtask_exithook -> nxsched_release_tcb
                            group_leave     || nxsched_releasepid & group_leave
                                            /\
                                           /  \
                                       switch out & waitpid()

Thread A group_leave in nxtask_exithook, switch out,
Thread B do waitpid(thread A) then meet traget thread A group is NULL, error.

Change-Id: Ia181d7a13aa645ec1c3141a45839fbf79db35b17
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2021-06-29 14:16:00 +08:00 committed by Xiang Xiao
parent b83b974e92
commit ece224a7e3
2 changed files with 12 additions and 7 deletions

View File

@ -167,9 +167,11 @@ int nx_waitid(int idtype, id_t id, FAR siginfo_t *info, int options)
*/
ctcb = nxsched_get_tcb((pid_t)id);
if (ctcb != NULL)
if (ctcb && ctcb->group)
{
if (ctcb->group->tg_ppid != rtcb->group->tg_pid)
/* Make sure that the thread it is our child. */
if (ctcb->group->tg_ppid != rtcb->pid)
{
ret = -ECHILD;
goto errout;
@ -209,7 +211,7 @@ int nx_waitid(int idtype, id_t id, FAR siginfo_t *info, int options)
ctcb = nxsched_get_tcb((pid_t)id);
if (ctcb == NULL || ctcb->group->tg_ppid != rtcb->group->tg_pid)
if (!ctcb || !ctcb->group || ctcb->group->tg_ppid != rtcb->pid)
{
ret = -ECHILD;
goto errout;

View File

@ -81,7 +81,11 @@ pid_t nx_waitpid(pid_t pid, int *stat_loc, int options)
/* Then the task group corresponding to this PID */
group = ctcb->group;
DEBUGASSERT(group);
if (group == NULL)
{
ret = -ECHILD;
goto errout;
}
/* Lock this group so that it cannot be deleted until the wait completes */
@ -230,7 +234,7 @@ pid_t nx_waitpid(pid_t pid, int *stat_loc, int options)
*/
ctcb = nxsched_get_tcb(pid);
if (ctcb != NULL)
if (ctcb && ctcb->group)
{
/* Make sure that the thread it is our child. */
@ -273,8 +277,7 @@ pid_t nx_waitpid(pid_t pid, int *stat_loc, int options)
*/
ctcb = nxsched_get_tcb(pid);
if (ctcb == NULL || ctcb->group->tg_ppid != rtcb->group->tg_pid)
if (!ctcb || !ctcb->group || ctcb->group->tg_ppid != rtcb->pid)
{
ret = -ECHILD;
goto errout;