Skip to content

Commit

Permalink
[LibOS] Add testcase for reproducing checkpoint on mmap() issue
Browse files Browse the repository at this point in the history
This test case will occasionally show the following error:

> while :; do gramine-direct fork_and_mmap; done
...
[P2:T3:fork_and_mmap] error: Sending IPC process-exit notification \
   failed: Connection reset by peer (ECONNRESET)

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
  • Loading branch information
stefanberger committed Feb 27, 2024
1 parent 2bfdb84 commit f1b0132
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
64 changes: 64 additions & 0 deletions libos/test/regression/fork_and_mmap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2023 IBM Corporation
* Stefan Berger <stefanb@linux.ibm.com>
*/

#define _GNU_SOURCE
#include <pthread.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

#define NUM_PAGES 1024

int proceed = 0;

static void* thread_func(void* arg) {
while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 0)
usleep(1);
proceed = 0;

usleep(1);
pid_t pid = fork();
if (pid < 0) {
perror("fork failed\n");
exit(1);
}
if (pid > 0) {
while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 0)
usleep(1);
printf("TEST OK\n");
} else {
printf("Child started\n");
}
exit(0);
}

int main(int argc, char** argv) {
long page_size = sysconf(_SC_PAGESIZE);
if (page_size == -1 && errno) {
err(1, "sysconf");
}


pthread_t forker;
if (pthread_create(&forker, NULL, thread_func, NULL) != 0) {
perror("pthread_create failed");
return 1;
}

proceed = 1;
while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 1);

size_t i;
for (i = 0; i < NUM_PAGES; i++)
mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

proceed = 1;
sleep(1);

return 0;
}
1 change: 1 addition & 0 deletions libos/test/regression/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ tests = {
'fork_and_close': {},
'fork_and_exec': {},
'fork_and_mprotect': {},
'fork_and_mmap': {},
'fork_and_munmap': {},
'fork_and_pthread_create': {},
'fork_and_sbrk': {},
Expand Down
7 changes: 7 additions & 0 deletions libos/test/regression/test_libos.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,13 @@ def test_164_fork_and_sbrk(self):
stdout, _ = self.run_binary(['fork_and_sbrk'])
self.assertIn("TEST OK", stdout)

def test_165_fork_and_mmap(self):
for _ in range(0, 10):
stdout, _ = self.run_binary(['fork_and_mmap'])
self.assertIn("TEST OK", stdout)
# error: Sending IPC process-exit notification failed: Connection reset by peer (ECONNRESET)
self.assertNotIn("ECONNRESET", stdout)

class TC_31_Syscall(RegressionTestCase):
def test_000_syscall_redirect(self):
stdout, _ = self.run_binary(['syscall'])
Expand Down
1 change: 1 addition & 0 deletions libos/test/regression/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ manifests = [
"fork_and_close",
"fork_and_exec",
"fork_and_mprotect",
"fork_and_mmap",
"fork_and_munmap",
"fork_and_pthread_create",
"fork_and_sbrk",
Expand Down
1 change: 1 addition & 0 deletions libos/test/regression/tests_musl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ manifests = [
"fork_and_close",
"fork_and_exec",
"fork_and_mprotect",
"fork_and_mmap",
"fork_and_munmap",
"fork_and_pthread_create",
"fork_and_sbrk",
Expand Down

0 comments on commit f1b0132

Please sign in to comment.