From 35a2f3af33a5dba1e0ba36587efced8fead97223 Mon Sep 17 00:00:00 2001 From: YOUR_NAME Date: Tue, 20 Jul 2021 18:21:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20init=E8=BF=9B=E7=A8=8B=E6=94=B6=E5=88=B0?= =?UTF-8?q?=E5=AD=90=E8=BF=9B=E7=A8=8B=E9=80=80=E5=87=BA=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E8=B0=83=E7=94=A8fork=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E6=8B=89=E8=B5=B7=E8=BF=9B=E7=A8=8B=EF=BC=8C=E4=BC=9A=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=B3=BB=E7=BB=9F=E5=8D=A1=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题原因:init进程执行信号时,线程栈底预留了部分空间给信号上下文使用, 从而导致处理信号时线程栈底比线程控制块里面记录的大,这样在fork的过程中内核 从init线程栈底copy线程上下文给新进程时,copy的不是实际运行的栈底,以致于 新进程的线程上下文不对,在实际运行时跑飞,引发系统卡死。 解决方案:在fork过程copy线程上下文时,判断是否预留了信号上下文空间,如果预留 了,则copy的栈底要基于预留后的栈底去copy线程上下文。 close: #I41HOY Signed-off-by: zff Change-Id: I61cb05183c78919730e3a68c1c85b72fa1decd16 --- arch/arm/arm/src/los_hw.c | 10 +++++++++- kernel/base/ipc/los_signal.c | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm/arm/src/los_hw.c b/arch/arm/arm/src/los_hw.c index 2db15a42..2c9584b9 100644 --- a/arch/arm/arm/src/los_hw.c +++ b/arch/arm/arm/src/los_hw.c @@ -105,7 +105,15 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStack, UINT32 parentStackSize) { - VOID *cloneStack = (VOID *)(((UINTPTR)parentTopOfStack + parentStackSize) - sizeof(TaskContext)); + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + VOID *cloneStack = NULL; + + if (sigcb->sigContext != NULL) { + cloneStack = (VOID *)((UINTPTR)sigcb->sigContext - sizeof(TaskContext)); + } else { + cloneStack = (VOID *)(((UINTPTR)parentTopOfStack + parentStackSize) - sizeof(TaskContext)); + } (VOID)memcpy_s(childStack, sizeof(TaskContext), cloneStack, sizeof(TaskContext)); ((TaskContext *)childStack)->R0 = 0; diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 43285ad4..ec7c5d59 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -678,6 +678,7 @@ VOID *OsRestorSignalContext(VOID *sp) LosProcessCB *process = OsCurrProcessGet(); VOID *saveContext = sigcb->sigContext; + sigcb->sigContext = NULL; sigcb->count--; process->sigShare = 0; OsProcessExitCodeSignalClear(process);