bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH gnumach 3/3] add rpc interrupted test


From: Luca Dariz
Subject: [PATCH gnumach 3/3] add rpc interrupted test
Date: Wed, 21 Aug 2024 18:36:16 +0200

* tests/test-machmsg.c: add two use cases used by glibc during signal
  handling
* tests/include/testlib.h
* tests/testlib.c: add new wait_thread_terminated() helper
---
 tests/include/testlib.h |  1 +
 tests/test-machmsg.c    | 80 +++++++++++++++++++++++++++++++++++++++++
 tests/testlib.c         | 15 ++++++++
 3 files changed, 96 insertions(+)

diff --git a/tests/include/testlib.h b/tests/include/testlib.h
index 1d08067b..737efd41 100644
--- a/tests/include/testlib.h
+++ b/tests/include/testlib.h
@@ -70,6 +70,7 @@ thread_t test_thread_start(task_t task, 
void(*routine)(void*), void* arg);
 mach_port_t host_priv(void);
 mach_port_t device_priv(void);
 void wait_thread_suspended(thread_t th);
+void wait_thread_terminated(thread_t th);
 
 extern vm_size_t vm_page_size;
 
diff --git a/tests/test-machmsg.c b/tests/test-machmsg.c
index ac292376..7f535bde 100644
--- a/tests/test-machmsg.c
+++ b/tests/test-machmsg.c
@@ -499,6 +499,83 @@ void test_msg_emptydesc(void)
 }
 
 
+void recv_to_be_interrupted(void *arg)
+{
+  mach_msg_header_t msg;
+  kern_return_t ret;
+  mach_port_t rcv_name;
+  long err = (long)arg;
+
+  ret = mach_port_allocate(mach_task_self (), MACH_PORT_RIGHT_RECEIVE, 
&rcv_name);
+  ASSERT_RET(ret, "creating rx port");
+
+  ret = mach_msg(&msg, MACH_RCV_MSG,
+                 0, sizeof(msg), rcv_name,
+                 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+  printf("mach_msg returned %x\n", ret);
+  ASSERT(ret == err, "recv not interrupted correctly");
+
+  thread_terminate(mach_thread_self());
+  FAILURE("thread_terminate");
+}
+
+void test_recv_interrupted(void)
+{
+  kern_return_t ret;
+  thread_t th;
+  th = test_thread_start(mach_task_self(), recv_to_be_interrupted, 
(void*)MACH_RCV_INTERRUPTED);
+  msleep(100);
+
+  ret = thread_suspend(th);
+  ASSERT_RET(ret, "thread_suspend");
+
+  ret = thread_abort(th);
+  ASSERT_RET(ret, "thread_abort");
+
+  ret = thread_resume(th);
+  ASSERT_RET(ret, "thread_resume");
+
+  wait_thread_terminated(th);
+}
+
+void test_recv_interrupted_setreturn(void)
+{
+  kern_return_t ret;
+  thread_t th;
+  th = test_thread_start(mach_task_self(), recv_to_be_interrupted, 
(void*)123L);
+  msleep(100);
+
+  ret = thread_suspend(th);
+  ASSERT_RET(ret, "thread_suspend");
+
+  ret = thread_abort(th);
+  ASSERT_RET(ret, "thread_abort");
+
+
+  struct i386_thread_state state;
+  unsigned int count;
+  count = i386_THREAD_STATE_COUNT;
+  ret = thread_get_state(th, i386_REGS_SEGS_STATE,
+                         (thread_state_t) &state, &count);
+  ASSERT_RET(ret, "thread_get_state()");
+
+#ifdef __i386__
+  state.eax = 123;
+#elif defined(__x86_64__)
+  state.rax = 123;
+#endif
+  ret = thread_set_state(th, i386_REGS_SEGS_STATE,
+                         (thread_state_t) &state, i386_THREAD_STATE_COUNT);
+  ASSERT_RET(ret, "thread_set_state");
+
+  ret = thread_resume(th);
+  ASSERT_RET(ret, "thread_resume");
+
+  wait_thread_terminated(th);
+}
+
+
 int
 main (int argc, char *argv[], int envc, char *envp[])
 {
@@ -512,5 +589,8 @@ main (int argc, char *argv[], int envc, char *envp[])
   test_msg_emptydesc();
   printf("test_iters()\n");
   test_iterations();
+  printf("test_recv_interrupted()\n");
+  test_recv_interrupted();
+  test_recv_interrupted_setreturn();
   return 0;
 }
diff --git a/tests/testlib.c b/tests/testlib.c
index df9d7113..4200979d 100644
--- a/tests/testlib.c
+++ b/tests/testlib.c
@@ -225,6 +225,21 @@ void wait_thread_suspended(thread_t th)
   } while (1);
 }
 
+void wait_thread_terminated(thread_t th)
+{
+  int err;
+  struct thread_basic_info info;
+  mach_msg_type_number_t count;
+  do {
+    count = THREAD_BASIC_INFO_COUNT;
+    err = thread_info(th, THREAD_BASIC_INFO, (thread_info_t)&info, &count);
+    if (err == MACH_SEND_INVALID_DEST)
+        break;
+    ASSERT_RET(err, "error in thread_info");
+    msleep(100); // don't poll continuously
+  } while (1);
+}
+
 /*
  * Minimal _start() for test modules, we just take the arguments from the
  * kernel, call main() and reboot. As in glibc, we expect the argument pointer
-- 
2.39.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]