sigsuspend: Make sure receive correct sigevent from do_kill

Change-Id: Ife9cf36a81f353e0575f6802f1e56f7dd4cb0425
Fujitsu: POSTK_DEBUG_TEMP_FIX_33
Refs: #1350
This commit is contained in:
Ken Sato
2019-08-23 15:24:35 +09:00
committed by Masamichi Takagi
parent 18412616e1
commit bc06d68d84
7 changed files with 228 additions and 10 deletions

View File

@ -4373,9 +4373,11 @@ SYSCALL_DECLARE(rt_sigtimedwait)
cpu_pause();
}
#ifdef POSTK_DEBUG_TEMP_FIX_33 /* sigevent missed fix */
/*
* Sending signal here is detected
* by the following list check
*/
thread->sigevent = 0;
#endif /* POSTK_DEBUG_TEMP_FIX_33 */
thread->status = PS_RUNNING;
lock = &thread->sigcommon->lock;
@ -4434,9 +4436,6 @@ SYSCALL_DECLARE(rt_sigtimedwait)
return -EINTR;
}
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
#ifndef POSTK_DEBUG_TEMP_FIX_33 /* sigevent missed fix */
thread->sigevent = 0;
#endif /* !POSTK_DEBUG_TEMP_FIX_33 */
}
if(info){
@ -4511,9 +4510,12 @@ do_sigsuspend(struct thread *thread, const sigset_t *set)
cpu_pause();
}
}
#ifdef POSTK_DEBUG_TEMP_FIX_33 /* sigevent missed fix */
/*
* Sending signal here is detected
* by the following list check
*/
thread->sigevent = 0;
#endif /* POSTK_DEBUG_TEMP_FIX_33 */
thread->status = PS_RUNNING;
lock = &thread->sigcommon->lock;
@ -4537,9 +4539,6 @@ do_sigsuspend(struct thread *thread, const sigset_t *set)
}
if(&pending->list == head){
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
#ifndef POSTK_DEBUG_TEMP_FIX_33 /* sigevent missed fix */
thread->sigevent = 0;
#endif /* POSTK_DEBUG_TEMP_FIX_33 */
continue;
}

64
test/issues/1350/C1350.c Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static int catch_cnt;
void sig_handler(int signum)
{
switch (signum) {
case SIGUSR1:
puts("suspender caught SIGUSR1");
catch_cnt++;
break;
default:
printf("suspender caught unexpected signal %d\n", signum);
}
fflush(stdout);
}
int main(void)
{
sigset_t sigset;
struct sigaction sact;
pid_t pid;
int ret = 0;
catch_cnt = 0;
if (fork() == 0) {
/* child (signal sender) */
sleep(3);
printf("child is sending SIGUSR1 (should be caught)\n");
kill(getppid(), SIGUSR1);
return 0;
}
/* parent (signal catcher) */
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = sig_handler;
if (sigaction(SIGUSR1, &sact, NULL) != 0) {
perror("sigaction() error");
ret = -1;
goto out;
}
sigfillset(&sigset);
sigdelset(&sigset, SIGUSR1);
printf("parent is waiting SIGUSR1\n");
if (sigsuspend(&sigset) == -1) {
printf("sigsuspend return -1 as expected\n");
}
if (catch_cnt == 1) {
printf("[OK] caught SIGUSR1\n");
}
else {
printf("[NG] SIGUSR1 count:%d\n", catch_cnt);
ret = -1;
goto out;
}
out:
return ret;
}

38
test/issues/1350/C1350.sh Executable file
View File

@ -0,0 +1,38 @@
#/bin/sh
USELTP=1
USEOSTEST=0
. ../../common.sh
issue=1350
tid=01
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
${MCEXEC} ./C1350
if [ $? -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
for tp in rt_sigsuspend01 sigsuspend01 pause01 pause02 pause03
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep TPASS $tp.txt | wc -l`
ng=`grep TFAIL $tp.txt | wc -l`
if [ $ng = 0 ]; then
echo "*** ${tname} PASSED ($ok)"
else
echo "*** ${tname} FAILED (ok=$ok ng=%ng)"
fi
let tid++
echo ""
done

11
test/issues/1350/Makefile Normal file
View File

@ -0,0 +1,11 @@
CFLAGS=-g
LDFLAGS=
TARGET=C1350
all: $(TARGET)
test: all
./C1350.sh
clean:
rm -f $(TARGET) *.o *.txt

35
test/issues/1350/README Normal file
View File

@ -0,0 +1,35 @@
【Issue#1350 動作確認】
□ テスト内容
1. Issueで報告された現象が再現しないことを確認
C1350T01:
Issueで報告されたRace-conditionが発生するよう、do_sigsuspendの復帰後、
thread->sigevent = 0の前に10秒間のsleep処理を行うパッチを適用し、
以下の処理を確認する
(1) 第1のプロセスがsigsuspendを呼ぶ
(2) 第1のプロセスがsigsuspendの、sigevent = 0;の直前に10秒sleepする
(3) 第2のプロセスが第1のプロセスにマスクされていないシグナルを送る
(4) 第1のプロセスがsigsuspendから返ることを確認する
2. 以下のLTPを用いて既存のsigsuspend機能に影響が無いことを確認
- rt_sigsuspend01
- sigsuspend01
- pause01
- pause02
- pause03
□ 実行手順
・下記の手順でテストを実行する
$ cd <mckernel>
$ patch -p0 < test/issues/1350/delay_sigsuspend.patch
(build mckernel)
$ cd test/issues/1350
$ make test
McKernelのインストール先や、OSTEST, LTPの配置場所は、
$HOME/.mck_test_config を参照している
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
$HOMEにコピーし、適宜編集する
□ 実行結果
x86_64result.log, aarch64_result.log 参照。
すべての項目をPASSしていることを確認。

View File

@ -0,0 +1,43 @@
*** C1350T01 start *******************************
parent is waiting SIGUSR1
child is sending SIGUSR1 (should be caught)
suspender caught SIGUSR1
sigsuspend return -1 as expected
[OK] caught SIGUSR1
*** C1350T01 PASSED ******************************
*** C1350T02 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
rt_sigsuspend01.c:53: PASS: rt_sigsuspend() returned with -1 and EINTR
rt_sigsuspend01.c:62: PASS: signal mask preserved
Summary:
passed 2
failed 0
skipped 0
warnings 0
*** C1350T02 PASSED (0)
*** C1350T03 start *******************************
sigsuspend01 1 TPASS : Functionality of sigsuspend() successful
*** C1350T03 PASSED (1)
*** C1350T04 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
pause01.c:35: PASS: pause() interrupted with EINTR
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1350T04 PASSED (0)
*** C1350T05 start *******************************
pause02 1 TPASS : pause was interrupted correctly
*** C1350T05 PASSED (1)
*** C1350T06 start *******************************
pause03 1 TPASS : pause() did not return after SIGKILL
*** C1350T06 PASSED (1)

View File

@ -0,0 +1,28 @@
*** C1350T01 start *******************************
parent is waiting SIGUSR1
child is sending SIGUSR1 (should be caught)
suspender caught SIGUSR1
sigsuspend return -1 as expected
[OK] caught SIGUSR1
*** C1350T01 PASSED ******************************
*** C1350T02 start *******************************
rt_sigsuspend01 1 TPASS : rt_sigsuspend PASSED
*** C1350T02 PASSED (1)
*** C1350T03 start *******************************
sigsuspend01 1 TPASS : Functionality of sigsuspend() successful
*** C1350T03 PASSED (1)
*** C1350T04 start *******************************
pause01 1 TPASS : pause() returned -1
*** C1350T04 PASSED (1)
*** C1350T05 start *******************************
pause02 1 TPASS : pause was interrupted correctly
*** C1350T05 PASSED (1)
*** C1350T06 start *******************************
pause03 1 TPASS : pause() did not return after SIGKILL
*** C1350T06 PASSED (1)