fix: memory leak due to forced termination during startup
Change-Id: Ide519f01702bfd17ae4576e04806b6d155ae846a refs: #1397
This commit is contained in:
committed by
Masamichi Takagi
parent
93581cb142
commit
9e2196c9ce
43
test/mcexec_signalonboot/README
Normal file
43
test/mcexec_signalonboot/README
Normal file
@@ -0,0 +1,43 @@
|
||||
==========
|
||||
How to run
|
||||
==========
|
||||
|
||||
(1) cd <mckernel> && patch -p1 < <mckernel>/test/mcexec_signalonboot/signal_injection.patch
|
||||
(2) Build McKernel
|
||||
(3) cd <mckernel>/test/mcexec_signalonboot
|
||||
(4) bash ./run.sh
|
||||
|
||||
============
|
||||
What to test
|
||||
============
|
||||
|
||||
Testing memory leaks in program booting.
|
||||
Terminate mcexec at some timing to check for memory leaks.
|
||||
|
||||
ID TIMING SIGNAL
|
||||
------------------------------------------
|
||||
001 MCEXEC_UP_PREPARE_IMAGE:before SIGINT
|
||||
002 MCEXEC_UP_PREPARE_IMAGE:before SIGKILL
|
||||
003 MCEXEC_UP_PREPARE_IMAGE:before SIGTERM
|
||||
011 MCEXEC_UP_PREPARE_IMAGE:after SIGINT
|
||||
012 MCEXEC_UP_PREPARE_IMAGE:after SIGKILL
|
||||
013 MCEXEC_UP_PREPARE_IMAGE:after SIGTERM
|
||||
101 MCEXEC_UP_TRANSFER:before SIGINT
|
||||
102 MCEXEC_UP_TRANSFER:before SIGKILL
|
||||
103 MCEXEC_UP_TRANSFER:before SIGTERM
|
||||
111 MCEXEC_UP_TRANSFER:after SIGINT
|
||||
112 MCEXEC_UP_TRANSFER:after SIGKILL
|
||||
113 MCEXEC_UP_TRANSFER:after SIGTERM
|
||||
201 init_sigaction:before SIGINT
|
||||
202 init_sigaction:before SIGKILL
|
||||
203 init_sigaction:before SIGTERM
|
||||
211 init_sigaction:after SIGINT
|
||||
212 init_sigaction:after SIGKILL
|
||||
213 init_sigaction:after SIGTERM
|
||||
301 MCEXEC_UP_START_IMAGE:before SIGINT
|
||||
302 MCEXEC_UP_START_IMAGE:before SIGKILL
|
||||
303 MCEXEC_UP_START_IMAGE:before SIGTERM
|
||||
311 MCEXEC_UP_START_IMAGE:after SIGINT
|
||||
312 MCEXEC_UP_START_IMAGE:after SIGKILL
|
||||
313 MCEXEC_UP_START_IMAGE:after SIGTERM
|
||||
------------------------------------------
|
||||
27
test/mcexec_signalonboot/result.log
Normal file
27
test/mcexec_signalonboot/result.log
Normal file
@@ -0,0 +1,27 @@
|
||||
[root@hostname mcexec_signalonboot]# sh run.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 12-59 -m 512M@4 ... done
|
||||
001: OK
|
||||
002: OK
|
||||
003: OK
|
||||
011: OK
|
||||
012: OK
|
||||
013: OK
|
||||
101: OK
|
||||
102: OK
|
||||
103: OK
|
||||
111: OK
|
||||
112: OK
|
||||
113: OK
|
||||
201: OK
|
||||
202: OK
|
||||
203: OK
|
||||
211: OK
|
||||
212: OK
|
||||
213: OK
|
||||
301: OK
|
||||
302: OK
|
||||
303: OK
|
||||
311: OK
|
||||
312: OK
|
||||
313: OK
|
||||
74
test/mcexec_signalonboot/run.sh
Normal file
74
test/mcexec_signalonboot/run.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# run.sh COPYRIGHT FUJITSU LIMITED 2019
|
||||
test_dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
#
|
||||
# init
|
||||
#
|
||||
. "${test_dir}/../common.sh"
|
||||
SIGINT=2
|
||||
SIGKILL=9
|
||||
SIGTERM=15
|
||||
|
||||
"$BIN/mcexec" -c 0 -- ls 2>&1 | grep -q "signal_injection.patch is applied."
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "signal_injection.patch is not been applied." >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
meminfo="/sys/devices/virtual/mcos/mcos0/sys/devices/system/node/node0/meminfo"
|
||||
exp_free_mem=`cat "$meminfo" | grep MemFree:`
|
||||
|
||||
#
|
||||
# run
|
||||
#
|
||||
test_cases=`cat <<__EOF__
|
||||
001 MCEXEC_UP_PREPARE_IMAGE:before $SIGINT
|
||||
002 MCEXEC_UP_PREPARE_IMAGE:before $SIGKILL
|
||||
003 MCEXEC_UP_PREPARE_IMAGE:before $SIGTERM
|
||||
011 MCEXEC_UP_PREPARE_IMAGE:after $SIGINT
|
||||
012 MCEXEC_UP_PREPARE_IMAGE:after $SIGKILL
|
||||
013 MCEXEC_UP_PREPARE_IMAGE:after $SIGTERM
|
||||
101 MCEXEC_UP_TRANSFER:before $SIGINT
|
||||
102 MCEXEC_UP_TRANSFER:before $SIGKILL
|
||||
103 MCEXEC_UP_TRANSFER:before $SIGTERM
|
||||
111 MCEXEC_UP_TRANSFER:after $SIGINT
|
||||
112 MCEXEC_UP_TRANSFER:after $SIGKILL
|
||||
113 MCEXEC_UP_TRANSFER:after $SIGTERM
|
||||
201 init_sigaction:before $SIGINT
|
||||
202 init_sigaction:before $SIGKILL
|
||||
203 init_sigaction:before $SIGTERM
|
||||
211 init_sigaction:after $SIGINT
|
||||
212 init_sigaction:after $SIGKILL
|
||||
213 init_sigaction:after $SIGTERM
|
||||
301 MCEXEC_UP_START_IMAGE:before $SIGINT
|
||||
302 MCEXEC_UP_START_IMAGE:before $SIGKILL
|
||||
303 MCEXEC_UP_START_IMAGE:before $SIGTERM
|
||||
311 MCEXEC_UP_START_IMAGE:after $SIGINT
|
||||
312 MCEXEC_UP_START_IMAGE:after $SIGKILL
|
||||
313 MCEXEC_UP_START_IMAGE:after $SIGTERM
|
||||
__EOF__`
|
||||
|
||||
IFS='
|
||||
'
|
||||
for tc in $test_cases
|
||||
do
|
||||
no=`echo $tc | awk '{print $1}'`
|
||||
opt_i=`echo $tc | awk '{print $2}'`
|
||||
opt_s=`echo $tc | awk '{print $3}'`
|
||||
echo -n "$no: "
|
||||
bash -c "'$BIN/mcexec' -c 0 -- -i $opt_i -s $opt_s ls >/dev/null 2>&1" \
|
||||
>/dev/null 2>&1
|
||||
sleep 1
|
||||
|
||||
free_mem=`cat "$meminfo" | grep MemFree:`
|
||||
if [ "$exp_free_mem" != "$free_mem" ]; then
|
||||
echo "NG - detected memory leak."
|
||||
echo " before: ${exp_free_mem}"
|
||||
echo " after: ${free_mem}"
|
||||
exp_free_mem=$free_mem
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
124
test/mcexec_signalonboot/signal_injection.patch
Normal file
124
test/mcexec_signalonboot/signal_injection.patch
Normal file
@@ -0,0 +1,124 @@
|
||||
diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c
|
||||
index 7f84284..3d65118 100644
|
||||
--- a/executer/user/mcexec.c
|
||||
+++ b/executer/user/mcexec.c
|
||||
@@ -200,6 +200,8 @@ static char *mpol_bind_nodes = NULL;
|
||||
static int uti_thread_rank = 0;
|
||||
static int uti_use_last_cpu = 0;
|
||||
static int enable_uti = 0;
|
||||
+static const char *signal_injection = "";
|
||||
+static int injection_signo = 0;
|
||||
|
||||
/* Partitioned execution (e.g., for MPI) */
|
||||
static int nr_processes = 0;
|
||||
@@ -892,11 +894,20 @@ int transfer_image(int fd, struct program_load_desc *desc)
|
||||
/* No more left to upload.. */
|
||||
if (lr == 0 && flen == 0) break;
|
||||
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_TRANSFER:before") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
+ printf("ioctl(MCEXEC_UP_TRANSFER)\n");
|
||||
if (ioctl(fd, MCEXEC_UP_TRANSFER,
|
||||
(unsigned long)&pt)) {
|
||||
perror("dma");
|
||||
break;
|
||||
}
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_TRANSFER:after") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2092,6 +2103,8 @@ int main(int argc, char **argv)
|
||||
__glob_argv = argv;
|
||||
#endif
|
||||
|
||||
+ printf("signal_injection.patch is applied.\n");
|
||||
+
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
page_mask = ~(page_size - 1);
|
||||
|
||||
@@ -2237,6 +2250,21 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
+ while ((opt = getopt_long(argc, argv, "i:s:",
|
||||
+ mcexec_options, NULL)) != -1) {
|
||||
+ switch (opt) {
|
||||
+ case 'i':
|
||||
+ signal_injection = optarg;
|
||||
+ break;
|
||||
+ case 's':
|
||||
+ injection_signo = strtol(optarg, NULL, 0);
|
||||
+ break;
|
||||
+ default: /* '?' */
|
||||
+ print_usage(argv);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (heap_extension == -1) {
|
||||
heap_extension = sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
@@ -2653,11 +2681,20 @@ int main(int argc, char **argv)
|
||||
desc->thp_disable = get_thp_disable();
|
||||
|
||||
/* user_start and user_end are set by this call */
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_PREPARE_IMAGE:before") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
+ printf("ioctl(MCEXEC_UP_PREPARE_IMAGE)\n");
|
||||
if (ioctl(fd, MCEXEC_UP_PREPARE_IMAGE, (unsigned long)desc) != 0) {
|
||||
perror("prepare");
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_PREPARE_IMAGE:after") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
|
||||
print_desc(desc);
|
||||
if (transfer_image(fd, desc) < 0) {
|
||||
@@ -2692,7 +2729,16 @@ int main(int argc, char **argv)
|
||||
__dprintf("mccmd server initialized\n");
|
||||
#endif
|
||||
|
||||
+ if (strcmp(signal_injection, "init_sigaction:before") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
+ printf("init_sigaction\n");
|
||||
init_sigaction();
|
||||
+ if (strcmp(signal_injection, "init_sigaction:after") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
|
||||
/* Initialize watchdog thread which detects hang of McKernel */
|
||||
|
||||
@@ -2721,11 +2767,20 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_START_IMAGE:before") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
+ printf("ioctl(MCEXEC_UP_START_IMAGE)\n");
|
||||
if (ioctl(fd, MCEXEC_UP_START_IMAGE, (unsigned long)desc) != 0) {
|
||||
perror("exec");
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
+ if (strcmp(signal_injection, "MCEXEC_UP_START_IMAGE:after") == 0) {
|
||||
+ printf("raise\n");
|
||||
+ raise(injection_signo);
|
||||
+ }
|
||||
|
||||
#if 1 /* debug : thread killed by exit_group() are still joinable? */
|
||||
join_all_threads();
|
||||
Reference in New Issue
Block a user