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/b871c710c52e
branches:  trunk
changeset: 932319:b871c710c52e
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 6b0b0d83b294 -r b871c710c52e 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