Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147519876
D10684.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D10684.id.diff
View Options
Index: head/tests/sys/kern/ptrace_test.c
===================================================================
--- head/tests/sys/kern/ptrace_test.c
+++ head/tests/sys/kern/ptrace_test.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/cpuset.h>
#include <sys/event.h>
+#include <sys/file.h>
#include <sys/time.h>
#include <sys/procctl.h>
#include <sys/ptrace.h>
@@ -3025,6 +3026,99 @@
ATF_REQUIRE(errno == ECHILD);
}
+static void *
+flock_thread(void *arg)
+{
+ int fd;
+
+ fd = *(int *)arg;
+ (void)flock(fd, LOCK_EX);
+ (void)flock(fd, LOCK_UN);
+ return (NULL);
+}
+
+/*
+ * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section.
+ * We rely on the fact that the lockf implementation sets SBDRY before blocking
+ * on a lock. This is a regression test for r318191.
+ */
+ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread);
+ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc)
+{
+ pthread_barrier_t barrier;
+ pthread_barrierattr_t battr;
+ char tmpfile[64];
+ pid_t child, wpid;
+ int error, fd, i, status;
+
+ ATF_REQUIRE(pthread_barrierattr_init(&battr) == 0);
+ ATF_REQUIRE(pthread_barrierattr_setpshared(&battr,
+ PTHREAD_PROCESS_SHARED) == 0);
+ ATF_REQUIRE(pthread_barrier_init(&barrier, &battr, 2) == 0);
+
+ (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX");
+ fd = mkstemp(tmpfile);
+ ATF_REQUIRE(fd >= 0);
+
+ ATF_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ pthread_t t[2];
+ int error, cfd;
+
+ error = pthread_barrier_wait(&barrier);
+ if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD)
+ _exit(1);
+
+ cfd = open(tmpfile, O_RDONLY);
+ if (cfd < 0)
+ _exit(1);
+
+ /*
+ * We want at least two threads blocked on the file lock since
+ * the SIGSTOP from PT_ATTACH may kick one of them out of
+ * sleep.
+ */
+ if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0)
+ _exit(1);
+ if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0)
+ _exit(1);
+ if (pthread_join(t[0], NULL) != 0)
+ _exit(1);
+ if (pthread_join(t[1], NULL) != 0)
+ _exit(1);
+ _exit(0);
+ }
+
+ ATF_REQUIRE(flock(fd, LOCK_EX) == 0);
+
+ error = pthread_barrier_wait(&barrier);
+ ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD);
+
+ /*
+ * Give the child some time to block. Is there a better way to do this?
+ */
+ sleep(1);
+
+ /*
+ * Attach and give the child 3 seconds to stop.
+ */
+ ATF_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) == 0);
+ for (i = 0; i < 3; i++) {
+ wpid = waitpid(child, &status, WNOHANG);
+ if (wpid == child && WIFSTOPPED(status) &&
+ WSTOPSIG(status) == SIGSTOP)
+ break;
+ sleep(1);
+ }
+ ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH");
+
+ ATF_REQUIRE(ptrace(PT_DETACH, child, NULL, 0) == 0);
+
+ ATF_REQUIRE(flock(fd, LOCK_UN) == 0);
+ ATF_REQUIRE(unlink(tmpfile) == 0);
+ ATF_REQUIRE(close(fd) == 0);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -3072,6 +3166,7 @@
ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1);
ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2);
ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard);
+ ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread);
return (atf_no_error());
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 12, 2:49 PM (5 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29552370
Default Alt Text
D10684.id.diff (3 KB)
Attached To
Mode
D10684: Add a regression test for r318191
Attached
Detach File
Event Timeline
Log In to Comment