Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/lib/libc/sys Move LWP tests out of t_ptrace_wait.c to ...
details: https://anonhg.NetBSD.org/src/rev/d94d37dfc70b
branches: trunk
changeset: 1009836:d94d37dfc70b
user: kamil <kamil%NetBSD.org@localhost>
date: Tue May 05 00:15:45 2020 +0000
description:
Move LWP tests out of t_ptrace_wait.c to t_ptrace_lwp_wait.h
The same tests are now included with the preprocessor in t_ptrace_wait.c.
No functional change intended.
diffstat:
tests/lib/libc/sys/t_ptrace_lwp_wait.h | 680 +++++++++++++++++++++++++++++++++
tests/lib/libc/sys/t_ptrace_wait.c | 668 +--------------------------------
2 files changed, 684 insertions(+), 664 deletions(-)
diffs (truncated from 1394 to 300 lines):
diff -r bc0a738e4c06 -r d94d37dfc70b tests/lib/libc/sys/t_ptrace_lwp_wait.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/libc/sys/t_ptrace_lwp_wait.h Tue May 05 00:15:45 2020 +0000
@@ -0,0 +1,680 @@
+/* $NetBSD: t_ptrace_lwp_wait.h,v 1.1 2020/05/05 00:15:45 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
+
+static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER;
+static volatile size_t lwpinfo_thread_done;
+
+static void *
+lwpinfo_thread(void *arg)
+{
+ sigset_t s;
+ volatile void **tcb;
+
+ tcb = (volatile void **)arg;
+
+ *tcb = _lwp_getprivate();
+ DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self());
+
+ pthread_setname_np(pthread_self(), "thread %d",
+ (void *)(intptr_t)_lwp_self());
+
+ sigemptyset(&s);
+ pthread_mutex_lock(&lwpinfo_thread_mtx);
+ sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
+ lwpinfo_thread_done++;
+ pthread_sigmask(SIG_BLOCK, &s, NULL);
+ pthread_cond_signal(&lwpinfo_thread_cnd);
+ pthread_mutex_unlock(&lwpinfo_thread_mtx);
+
+ return infinite_thread(NULL);
+}
+
+static void
+traceme_lwpinfo(const size_t threads, const char *iter)
+{
+ const int sigval = SIGSTOP;
+ const int sigval2 = SIGINT;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct ptrace_lwpinfo lwp = {0, 0};
+ struct ptrace_lwpstatus lwpstatus = {0};
+ struct ptrace_siginfo info;
+ void *private;
+ char *name;
+ char namebuf[PL_LNAMELEN];
+ volatile void *tcb[4];
+ bool found;
+ sigset_t s;
+
+ /* Maximum number of supported threads in this test */
+ pthread_t t[__arraycount(tcb) - 1];
+ size_t n, m;
+ int rv;
+ size_t bytes_read;
+
+ struct ptrace_io_desc io;
+ sigset_t sigmask;
+
+ ATF_REQUIRE(__arraycount(t) >= threads);
+ memset(tcb, 0, sizeof(tcb));
+
+ DPRINTF("Before forking process PID=%d\n", getpid());
+ SYSCALL_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ tcb[0] = _lwp_getprivate();
+ DPRINTF("Storing tcb[0] = %p\n", tcb[0]);
+
+ pthread_setname_np(pthread_self(), "thread %d",
+ (void *)(intptr_t)_lwp_self());
+
+ sigemptyset(&s);
+ sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
+ pthread_sigmask(SIG_BLOCK, &s, NULL);
+
+ DPRINTF("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ for (n = 0; n < threads; n++) {
+ rv = pthread_create(&t[n], NULL, lwpinfo_thread,
+ &tcb[n + 1]);
+ FORKEE_ASSERT(rv == 0);
+ }
+
+ pthread_mutex_lock(&lwpinfo_thread_mtx);
+ while (lwpinfo_thread_done < threads) {
+ pthread_cond_wait(&lwpinfo_thread_cnd,
+ &lwpinfo_thread_mtx);
+ }
+ pthread_mutex_unlock(&lwpinfo_thread_mtx);
+
+ DPRINTF("Before raising %s from child\n", strsignal(sigval2));
+ FORKEE_ASSERT(raise(sigval2) == 0);
+
+ /* NOTREACHED */
+ FORKEE_ASSERTX(0 && "Not reached");
+ }
+ DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
+ SYSCALL_REQUIRE(
+ ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
+
+ DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
+ DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
+ info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
+ info.psi_siginfo.si_errno);
+
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
+
+ if (strstr(iter, "LWPINFO") != NULL) {
+ DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
+ != -1);
+
+ DPRINTF("Assert that there exists a single thread only\n");
+ ATF_REQUIRE(lwp.pl_lwpid > 0);
+
+ DPRINTF("Assert that lwp thread %d received event "
+ "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
+ FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
+
+ if (strstr(iter, "LWPSTATUS") != NULL) {
+ DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS "
+ "for child\n");
+ lwpstatus.pl_lwpid = lwp.pl_lwpid;
+ SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus,
+ sizeof(lwpstatus)) != -1);
+ }
+
+ DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
+ != -1);
+
+ DPRINTF("Assert that there exists a single thread only\n");
+ ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
+ } else {
+ DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
+ sizeof(lwpstatus)) != -1);
+
+ DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid);
+ ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
+
+ DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
+ sizeof(lwpstatus)) != -1);
+
+ DPRINTF("Assert that there exists a single thread only\n");
+ ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
+ }
+
+ DPRINTF("Before resuming the child process where it left off and "
+ "without signal to be sent\n");
+ SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval2);
+
+ DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
+ SYSCALL_REQUIRE(
+ ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
+
+ DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
+ DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
+ info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
+ info.psi_siginfo.si_errno);
+
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
+
+ memset(&lwp, 0, sizeof(lwp));
+ memset(&lwpstatus, 0, sizeof(lwpstatus));
+
+ memset(&io, 0, sizeof(io));
+
+ bytes_read = 0;
+ io.piod_op = PIOD_READ_D;
+ io.piod_len = sizeof(tcb);
+
+ do {
+ io.piod_addr = (char *)&tcb + bytes_read;
+ io.piod_offs = io.piod_addr;
+
+ rv = ptrace(PT_IO, child, &io, sizeof(io));
+ ATF_REQUIRE(rv != -1 && io.piod_len != 0);
+
+ bytes_read += io.piod_len;
+ io.piod_len = sizeof(tcb) - bytes_read;
+ } while (bytes_read < sizeof(tcb));
+
+ for (n = 0; n <= threads; n++) {
+ if (strstr(iter, "LWPINFO") != NULL) {
+ DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
+ "child\n");
+ SYSCALL_REQUIRE(
+ ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
+ DPRINTF("LWP=%d\n", lwp.pl_lwpid);
+
+ DPRINTF("Assert that the thread exists\n");
+ ATF_REQUIRE(lwp.pl_lwpid > 0);
+
+ DPRINTF("Assert that lwp thread %d received expected "
+ "event\n", lwp.pl_lwpid);
+ FORKEE_ASSERT_EQ(lwp.pl_event,
+ info.psi_lwpid == lwp.pl_lwpid ?
+ PL_EVENT_SIGNAL : PL_EVENT_NONE);
+
+ if (strstr(iter, "LWPSTATUS") != NULL) {
+ DPRINTF("Before calling ptrace(2) with "
+ "PT_LWPSTATUS for child\n");
+ lwpstatus.pl_lwpid = lwp.pl_lwpid;
+ SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child,
+ &lwpstatus, sizeof(lwpstatus)) != -1);
+
+ goto check_lwpstatus;
+ }
+ } else {
+ DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for "
+ "child\n");
+ SYSCALL_REQUIRE(
+ ptrace(PT_LWPNEXT, child, &lwpstatus,
+ sizeof(lwpstatus)) != -1);
+ DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid);
+
+ DPRINTF("Assert that the thread exists\n");
+ ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
+
+ check_lwpstatus:
+
+ if (strstr(iter, "pl_sigmask") != NULL) {
+ sigmask = lwpstatus.pl_sigmask;
+
+ DPRINTF("Retrieved sigmask: "
+ "%02x%02x%02x%02x\n",
+ sigmask.__bits[0], sigmask.__bits[1],
+ sigmask.__bits[2], sigmask.__bits[3]);
+
+ found = false;
+ for (m = 0;
+ m < __arraycount(lwpinfo_thread_sigmask);
+ m++) {
+ if (sigismember(&sigmask,
+ lwpinfo_thread_sigmask[m])) {
+ found = true;
+ lwpinfo_thread_sigmask[m] = 0;
+ break;
+ }
+ }
+ ATF_REQUIRE(found == true);
+ } else if (strstr(iter, "pl_name") != NULL) {
+ name = lwpstatus.pl_name;
+
+ DPRINTF("Retrieved thread name: "
+ "%s\n", name);
+
Home |
Main Index |
Thread Index |
Old Index