mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 05:55:46 +08:00
Fix some problems with the vfork() test on the STM32F3Discovery
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5628 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -280,7 +280,7 @@ CONFIG_DEV_CONSOLE=y
|
|||||||
# CONFIG_FDCLONE_STDIO is not set
|
# CONFIG_FDCLONE_STDIO is not set
|
||||||
CONFIG_SDCLONE_DISABLE=y
|
CONFIG_SDCLONE_DISABLE=y
|
||||||
# CONFIG_SCHED_WORKQUEUE is not set
|
# CONFIG_SCHED_WORKQUEUE is not set
|
||||||
# CONFIG_SCHED_WAITPID is not set
|
CONFIG_SCHED_WAITPID=y
|
||||||
# CONFIG_SCHED_STARTHOOK is not set
|
# CONFIG_SCHED_STARTHOOK is not set
|
||||||
# CONFIG_SCHED_ATEXIT is not set
|
# CONFIG_SCHED_ATEXIT is not set
|
||||||
# CONFIG_SCHED_ONEXIT is not set
|
# CONFIG_SCHED_ONEXIT is not set
|
||||||
|
|||||||
+7
-1
@@ -44,11 +44,17 @@ MISC_SRCS += sched_garbage.c sched_getfiles.c sched_getsockets.c sched_getstream
|
|||||||
TSK_SRCS = prctl.c exit.c getpid.c
|
TSK_SRCS = prctl.c exit.c getpid.c
|
||||||
TSK_SRCS += task_create.c task_init.c task_setup.c task_activate.c task_start.c
|
TSK_SRCS += task_create.c task_init.c task_setup.c task_activate.c task_start.c
|
||||||
TSK_SRCS += task_delete.c task_deletecurrent.c task_exithook.c task_recover.c
|
TSK_SRCS += task_delete.c task_deletecurrent.c task_exithook.c task_recover.c
|
||||||
TSK_SRCS += task_restart.c task_spawn.c task_spawnparms.c task_vfork.c
|
TSK_SRCS += task_restart.c task_spawn.c task_spawnparms.c
|
||||||
TSK_SRCS += sched_addreadytorun.c sched_removereadytorun.c sched_addprioritized.c
|
TSK_SRCS += sched_addreadytorun.c sched_removereadytorun.c sched_addprioritized.c
|
||||||
TSK_SRCS += sched_mergepending.c sched_addblocked.c sched_removeblocked.c
|
TSK_SRCS += sched_mergepending.c sched_addblocked.c sched_removeblocked.c
|
||||||
TSK_SRCS += sched_free.c sched_gettcb.c sched_verifytcb.c sched_releasetcb.c
|
TSK_SRCS += sched_free.c sched_gettcb.c sched_verifytcb.c sched_releasetcb.c
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
|
||||||
|
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||||
|
TSK_SRCS += task_vfork.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(CONFIG_BINFMT_DISABLE),y)
|
ifneq ($(CONFIG_BINFMT_DISABLE),y)
|
||||||
ifeq ($(CONFIG_LIBC_EXECFUNCS),y)
|
ifeq ($(CONFIG_LIBC_EXECFUNCS),y)
|
||||||
TSK_SRCS += task_posixspawn.c
|
TSK_SRCS += task_posixspawn.c
|
||||||
|
|||||||
+5
-29
@@ -54,6 +54,9 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
/* vfork() requires architecture-specific support as well as waipid(). */
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -220,9 +223,7 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child)
|
|||||||
#endif
|
#endif
|
||||||
FAR const char *name;
|
FAR const char *name;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
#ifdef CONFIG_SCHED_WAITPID
|
|
||||||
int rc;
|
int rc;
|
||||||
#endif
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
svdbg("Starting Child TCB=%p, parent=%p\n", child, g_readytorun.head);
|
svdbg("Starting Child TCB=%p, parent=%p\n", child, g_readytorun.head);
|
||||||
@@ -279,8 +280,6 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child)
|
|||||||
* after the parent thread again?
|
* after the parent thread again?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_WAITPID
|
|
||||||
|
|
||||||
/* We can also exploit a bug in the execv() implementation: The PID
|
/* We can also exploit a bug in the execv() implementation: The PID
|
||||||
* of the task exec'ed by the child will not be the same as the PID of
|
* of the task exec'ed by the child will not be the same as the PID of
|
||||||
* the child task. Therefore, waitpid() on the child task's PID will
|
* the child task. Therefore, waitpid() on the child task's PID will
|
||||||
@@ -299,31 +298,6 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child)
|
|||||||
(void)waitpid(pid, &rc, 0);
|
(void)waitpid(pid, &rc, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
|
||||||
/* The following logic does not appear to work... It gets stuff in an
|
|
||||||
* infinite kill() loop and hogs the processor. Therefore, it looks
|
|
||||||
* as though CONFIG_SCHED_WAITPID may be a requirement to used vfork().
|
|
||||||
*
|
|
||||||
* Again exploiting that execv() bug: Check if the child thread is
|
|
||||||
* still running.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (kill(pid, 0) == OK)
|
|
||||||
{
|
|
||||||
/* Yes.. then we can yield to it -- assuming that it has not lowered
|
|
||||||
* its priority. sleep(0) might be a safer thing to do since it does
|
|
||||||
* not depend on prioirities: It will halt the parent thread for one
|
|
||||||
* system clock tick. This will delay the return to the parent thread.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
|
||||||
sleep(0);
|
|
||||||
#else
|
|
||||||
sched_yield();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,3 +323,5 @@ void task_vforkabort(FAR struct task_tcb_s *child, int errcode)
|
|||||||
sched_releasetcb((FAR struct tcb_s *)child);
|
sched_releasetcb((FAR struct tcb_s *)child);
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_ARCH_HAVE_VFORK && CONFIG_SCHED_WAITPID */
|
||||||
|
|||||||
Reference in New Issue
Block a user