Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150492375
D7044.id18218.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D7044.id18218.diff
View Options
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -53,6 +53,7 @@
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/pioctl.h>
+#include <sys/ptrace.h>
#include <sys/namei.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
@@ -906,7 +907,8 @@
if (error == 0) {
PROC_LOCK(p);
- td->td_dbgflags |= TDB_EXEC;
+ if (p->p_ptevents & PTRACE_EXEC)
+ td->td_dbgflags |= TDB_EXEC;
PROC_UNLOCK(p);
/*
Index: sys/kern/kern_exit.c
===================================================================
--- sys/kern/kern_exit.c
+++ sys/kern/kern_exit.c
@@ -338,6 +338,7 @@
PROC_LOCK(p);
stopprofclock(p);
p->p_flag &= ~(P_TRACED | P_PPWAIT | P_PPTRACE);
+ p->p_ptevents = 0;
/*
* Stop the real interval timer. If the handler is currently
@@ -475,6 +476,7 @@
*/
clear_orphan(q);
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
+ q->p_ptevents = 0;
FOREACH_THREAD_IN_PROC(q, tdt)
tdt->td_dbgflags &= ~TDB_SUSPEND;
kern_psignal(q, SIGKILL);
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -720,8 +720,7 @@
* but before we wait for the debugger.
*/
_PHOLD(p2);
- if ((p1->p_flag & (P_TRACED | P_FOLLOWFORK)) == (P_TRACED |
- P_FOLLOWFORK)) {
+ if (p1->p_ptevents & PTRACE_FORK) {
/*
* Arrange for debugger to receive the fork event.
*
@@ -1064,14 +1063,14 @@
if (td->td_dbgflags & TDB_STOPATFORK) {
sx_xlock(&proctree_lock);
PROC_LOCK(p);
- if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) ==
- (P_TRACED | P_FOLLOWFORK)) {
+ if (p->p_pptr->p_ptevents & PTRACE_FORK) {
/*
* If debugger still wants auto-attach for the
* parent's children, do it now.
*/
dbg = p->p_pptr->p_pptr;
p->p_flag |= P_TRACED;
+ p->p_ptevents = p->p_pptr->p_ptevents;
p->p_oppid = p->p_pptr->p_pid;
CTR2(KTR_PTRACE,
"fork_return: attaching to new child pid %d: oppid %d",
@@ -1098,7 +1097,7 @@
PROC_LOCK(p);
td->td_dbgflags |= TDB_SCX;
_STOPEVENT(p, S_SCX, td->td_dbg_sc_code);
- if ((p->p_stops & S_PT_SCX) != 0 ||
+ if ((p->p_ptevents & PTRACE_SCX) != 0 ||
(td->td_dbgflags & TDB_BORN) != 0)
ptracestop(td, SIGTRAP);
td->td_dbgflags &= ~(TDB_SCX | TDB_BORN);
Index: sys/kern/kern_sig.c
===================================================================
--- sys/kern/kern_sig.c
+++ sys/kern/kern_sig.c
@@ -2188,9 +2188,10 @@
!((prop & SA_CONT) && (p->p_flag & P_STOPPED_SIG)))
return (ret);
/*
- * SIGKILL: Remove procfs STOPEVENTs.
+ * SIGKILL: Remove procfs STOPEVENTs and ptrace events.
*/
if (sig == SIGKILL) {
+ p->p_ptevents = 0;
/* from procfs_ioctl.c: PIOCBIC */
p->p_stops = 0;
/* from procfs_ioctl.c: PIOCCONT */
Index: sys/kern/kern_thr.c
===================================================================
--- sys/kern/kern_thr.c
+++ sys/kern/kern_thr.c
@@ -36,6 +36,7 @@
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/posix4.h>
+#include <sys/ptrace.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
@@ -253,7 +254,7 @@
thread_unlock(td);
if (P_SHOULDSTOP(p))
newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
- if (p->p_flag2 & P2_LWP_EVENTS)
+ if (p->p_ptevents & PTRACE_LWP)
newtd->td_dbgflags |= TDB_BORN;
/*
@@ -353,7 +354,7 @@
p->p_pendingexits++;
td->td_dbgflags |= TDB_EXIT;
- if (p->p_flag & P_TRACED && p->p_flag2 & P2_LWP_EVENTS)
+ if (p->p_ptevents & PTRACE_LWP)
ptracestop(td, SIGTRAP);
PROC_UNLOCK(p);
tidhash_remove(td);
Index: sys/kern/subr_syscall.c
===================================================================
--- sys/kern/subr_syscall.c
+++ sys/kern/subr_syscall.c
@@ -87,7 +87,7 @@
PROC_LOCK(p);
td->td_dbg_sc_code = sa->code;
td->td_dbg_sc_narg = sa->narg;
- if (p->p_stops & S_PT_SCE)
+ if (p->p_ptevents & PTRACE_SCE)
ptracestop((td), SIGTRAP);
PROC_UNLOCK(p);
}
@@ -208,7 +208,7 @@
*/
if (traced &&
((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 ||
- (p->p_stops & S_PT_SCX) != 0))
+ (p->p_ptevents & PTRACE_SCX) != 0))
ptracestop(td, SIGTRAP);
td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK);
PROC_UNLOCK(p);
Index: sys/kern/sys_process.c
===================================================================
--- sys/kern/sys_process.c
+++ sys/kern/sys_process.c
@@ -586,6 +586,7 @@
struct ptrace_lwpinfo32 pl32;
struct ptrace_vm_entry32 pve32;
#endif
+ int ptevents;
} r;
void *addr;
int error = 0;
@@ -600,6 +601,7 @@
AUDIT_ARG_VALUE(uap->data);
addr = &r;
switch (uap->req) {
+ case PT_GET_EVENT_MASK:
case PT_GETREGS:
case PT_GETFPREGS:
case PT_GETDBREGS:
@@ -614,6 +616,12 @@
case PT_SETDBREGS:
error = COPYIN(uap->addr, &r.dbreg, sizeof r.dbreg);
break;
+ case PT_SET_EVENT_MASK:
+ if (uap->data != sizeof(r.ptevents))
+ error = EINVAL;
+ else
+ error = copyin(uap->addr, &r.ptevents, uap->data);
+ break;
case PT_IO:
error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
break;
@@ -647,6 +655,9 @@
case PT_GETDBREGS:
error = COPYOUT(&r.dbreg, uap->addr, sizeof r.dbreg);
break;
+ case PT_GET_EVENT_MASK:
+ error = copyout(&r.ptevents, uap->addr, uap->data);
+ break;
case PT_LWPINFO:
error = copyout(&r.pl, uap->addr, uap->data);
break;
@@ -711,6 +722,8 @@
case PT_SYSCALL:
case PT_FOLLOW_FORK:
case PT_LWP_EVENTS:
+ case PT_GET_EVENT_MASK:
+ case PT_SET_EVENT_MASK:
case PT_DETACH:
sx_xlock(&proctree_lock);
proctree_locked = 1;
@@ -885,6 +898,7 @@
case PT_TRACE_ME:
/* set my trace flag and "owner" so it can read/write me */
p->p_flag |= P_TRACED;
+ p->p_ptevents = PTRACE_DEFAULT;
if (p->p_flag & P_PPWAIT)
p->p_flag |= P_PPTRACE;
p->p_oppid = p->p_pptr->p_pid;
@@ -903,6 +917,7 @@
* on a "detach".
*/
p->p_flag |= P_TRACED;
+ p->p_ptevents = PTRACE_DEFAULT;
p->p_oppid = p->p_pptr->p_pid;
if (p->p_pptr != td->td_proc) {
proc_reparent(p, td->td_proc);
@@ -941,24 +956,50 @@
case PT_FOLLOW_FORK:
CTR3(KTR_PTRACE, "PT_FOLLOW_FORK: pid %d %s -> %s", p->p_pid,
- p->p_flag & P_FOLLOWFORK ? "enabled" : "disabled",
+ p->p_ptevents & PTRACE_FORK ? "enabled" : "disabled",
data ? "enabled" : "disabled");
if (data)
- p->p_flag |= P_FOLLOWFORK;
+ p->p_ptevents |= PTRACE_FORK;
else
- p->p_flag &= ~P_FOLLOWFORK;
+ p->p_ptevents &= ~PTRACE_FORK;
break;
case PT_LWP_EVENTS:
CTR3(KTR_PTRACE, "PT_LWP_EVENTS: pid %d %s -> %s", p->p_pid,
- p->p_flag2 & P2_LWP_EVENTS ? "enabled" : "disabled",
+ p->p_ptevents & PTRACE_LWP ? "enabled" : "disabled",
data ? "enabled" : "disabled");
if (data)
- p->p_flag2 |= P2_LWP_EVENTS;
+ p->p_ptevents |= PTRACE_LWP;
else
- p->p_flag2 &= ~P2_LWP_EVENTS;
+ p->p_ptevents &= ~PTRACE_LWP;
+ break;
+
+ case PT_GET_EVENT_MASK:
+ if (data != sizeof(p->p_ptevents)) {
+ error = EINVAL;
+ break;
+ }
+ CTR2(KTR_PTRACE, "PT_GET_EVENT_MASK: pid %d mask %#x", p->p_pid,
+ p->p_ptevents);
+ *(int *)addr = p->p_ptevents;
break;
+ case PT_SET_EVENT_MASK:
+ if (data != sizeof(p->p_ptevents)) {
+ error = EINVAL;
+ break;
+ }
+ tmp = *(int *)addr;
+ if ((tmp & ~(PTRACE_EXEC | PTRACE_SCE | PTRACE_SCX |
+ PTRACE_FORK | PTRACE_LWP)) != 0) {
+ error = EINVAL;
+ break;
+ }
+ CTR3(KTR_PTRACE, "PT_SET_EVENT_MASK: pid %d mask %#x -> %#x",
+ p->p_pid, p->p_ptevents, tmp);
+ p->p_ptevents = tmp;
+ break;
+
case PT_STEP:
case PT_CONTINUE:
case PT_TO_SCE:
@@ -991,24 +1032,24 @@
}
switch (req) {
case PT_TO_SCE:
- p->p_stops |= S_PT_SCE;
+ p->p_ptevents |= PTRACE_SCE;
CTR4(KTR_PTRACE,
- "PT_TO_SCE: pid %d, stops = %#x, PC = %#lx, sig = %d",
- p->p_pid, p->p_stops,
+ "PT_TO_SCE: pid %d, events = %#x, PC = %#lx, sig = %d",
+ p->p_pid, p->p_ptevents,
(u_long)(uintfptr_t)addr, data);
break;
case PT_TO_SCX:
- p->p_stops |= S_PT_SCX;
+ p->p_ptevents |= PTRACE_SCX;
CTR4(KTR_PTRACE,
- "PT_TO_SCX: pid %d, stops = %#x, PC = %#lx, sig = %d",
- p->p_pid, p->p_stops,
+ "PT_TO_SCX: pid %d, events = %#x, PC = %#lx, sig = %d",
+ p->p_pid, p->p_ptevents,
(u_long)(uintfptr_t)addr, data);
break;
case PT_SYSCALL:
- p->p_stops |= S_PT_SCE | S_PT_SCX;
+ p->p_ptevents |= PTRACE_SYSCALL;
CTR4(KTR_PTRACE,
- "PT_SYSCALL: pid %d, stops = %#x, PC = %#lx, sig = %d",
- p->p_pid, p->p_stops,
+ "PT_SYSCALL: pid %d, events = %#x, PC = %#lx, sig = %d",
+ p->p_pid, p->p_ptevents,
(u_long)(uintfptr_t)addr, data);
break;
case PT_CONTINUE:
@@ -1027,7 +1068,7 @@
* parent. Otherwise the debugee will be set
* as an orphan of the debugger.
*/
- p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
+ p->p_flag &= ~(P_TRACED | P_WAITED);
if (p->p_oppid != p->p_pptr->p_pid) {
PROC_LOCK(p->p_pptr);
sigqueue_take(p->p_ksi);
@@ -1044,7 +1085,7 @@
CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d",
p->p_pid, data);
p->p_oppid = 0;
- p->p_stops = 0;
+ p->p_ptevents = 0;
/* should we send SIGCHLD? */
/* childproc_continued(p); */
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -573,6 +573,7 @@
u_int p_stype; /* (c) Stop event type. */
char p_step; /* (c) Process is stopped. */
u_char p_pfsflags; /* (c) Procfs flags. */
+ u_int p_ptevents; /* (c) ptrace() event mask. */
struct nlminfo *p_nlminfo; /* (?) Only used by/for lockd. */
struct kaioinfo *p_aioinfo; /* (y) ASYNC I/O info. */
struct thread *p_singlethread;/* (c + j) If single threading this is it */
@@ -664,7 +665,7 @@
#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
#define P_KPROC 0x00004 /* Kernel process. */
-#define P_FOLLOWFORK 0x00008 /* Attach parent debugger to children. */
+#define P_UNUSED3 0x00008 /* --available-- */
#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
#define P_PROFIL 0x00020 /* Has started profiling. */
#define P_STOPPROF 0x00040 /* Has thread requesting to stop profiling. */
@@ -703,7 +704,6 @@
#define P2_NOTRACE 0x00000002 /* No ptrace(2) attach or coredumps. */
#define P2_NOTRACE_EXEC 0x00000004 /* Keep P2_NOPTRACE on exec(2). */
#define P2_AST_SU 0x00000008 /* Handles SU ast for kthreads. */
-#define P2_LWP_EVENTS 0x00000010 /* Report LWP events via ptrace(2). */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
Index: sys/sys/ptrace.h
===================================================================
--- sys/sys/ptrace.h
+++ sys/sys/ptrace.h
@@ -66,6 +66,9 @@
#define PT_FOLLOW_FORK 23
#define PT_LWP_EVENTS 24 /* report LWP birth and exit */
+#define PT_GET_EVENT_MASK 25 /* get mask of optional events */
+#define PT_SET_EVENT_MASK 26 /* set mask of optional events */
+
#define PT_GETREGS 33 /* get general-purpose registers */
#define PT_SETREGS 34 /* set general-purpose registers */
#define PT_GETFPREGS 35 /* get floating-point registers */
@@ -79,6 +82,16 @@
#define PT_FIRSTMACH 64 /* for machine-specific requests */
#include <machine/ptrace.h> /* machine-specific requests, if any */
+/* Events used with PT_GET_EVENT_MASK and PT_SET_EVENT_MASK */
+#define PTRACE_EXEC 0x0001
+#define PTRACE_SCE 0x0002
+#define PTRACE_SCX 0x0004
+#define PTRACE_SYSCALL (PTRACE_SCE | PTRACE_SCX)
+#define PTRACE_FORK 0x0008
+#define PTRACE_LWP 0x0010
+
+#define PTRACE_DEFAULT (PTRACE_EXEC)
+
struct ptrace_io_desc {
int piod_op; /* I/O operation */
void *piod_offs; /* child offset */
@@ -136,13 +149,6 @@
#ifdef _KERNEL
-/*
- * The flags below are used for ptrace(2) tracing and have no relation
- * to procfs. They are stored in struct proc's p_stops member.
- */
-#define S_PT_SCE 0x000010000
-#define S_PT_SCX 0x000020000
-
int ptrace_set_pc(struct thread *_td, unsigned long _addr);
int ptrace_single_step(struct thread *_td);
int ptrace_clear_single_step(struct thread *_td);
Index: tests/sys/kern/ptrace_test.c
===================================================================
--- tests/sys/kern/ptrace_test.c
+++ tests/sys/kern/ptrace_test.c
@@ -1355,6 +1355,200 @@
ATF_REQUIRE(errno == ECHILD);
}
+static void
+handler(int sig __unused)
+{
+}
+
+static void
+signal_main(void)
+{
+
+ signal(SIGINFO, handler);
+ raise(SIGINFO);
+ exit(0);
+}
+
+/*
+ * Verify that the expected ptrace event is reported for a signal.
+ */
+ATF_TC_WITHOUT_HEAD(ptrace__siginfo);
+ATF_TC_BODY(ptrace__siginfo, tc)
+{
+ struct ptrace_lwpinfo pl;
+ pid_t fpid, wpid;
+ int status;
+
+ ATF_REQUIRE((fpid = fork()) != -1);
+ if (fpid == 0) {
+ trace_me();
+ signal_main();
+ }
+
+ /* The first wait() should report the stop from SIGSTOP. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* The next event should be for the SIGINFO. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGINFO);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE(pl.pl_event == PL_EVENT_SIGNAL);
+ ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI);
+ ATF_REQUIRE(pl.pl_siginfo.si_code == SI_LWP);
+ ATF_REQUIRE(pl.pl_siginfo.si_pid == wpid);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* The last event should be for the child process's exit. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE(WEXITSTATUS(status) == 0);
+
+ wpid = wait(&status);
+ ATF_REQUIRE(wpid == -1);
+ ATF_REQUIRE(errno == ECHILD);
+}
+
+/*
+ * Verify that the expected ptrace events are reported for PTRACE_EXEC.
+ */
+ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable);
+ATF_TC_BODY(ptrace__ptrace_exec_disable, tc)
+{
+ pid_t fpid, wpid;
+ int events, status;
+
+ ATF_REQUIRE((fpid = fork()) != -1);
+ if (fpid == 0) {
+ trace_me();
+ exec_thread(NULL);
+ }
+
+ /* The first wait() should report the stop from SIGSTOP. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
+
+ events = 0;
+ ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* Should get one event at exit. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE(WEXITSTATUS(status) == 0);
+
+ wpid = wait(&status);
+ ATF_REQUIRE(wpid == -1);
+ ATF_REQUIRE(errno == ECHILD);
+}
+
+ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable);
+ATF_TC_BODY(ptrace__ptrace_exec_enable, tc)
+{
+ struct ptrace_lwpinfo pl;
+ pid_t fpid, wpid;
+ int events, status;
+
+ ATF_REQUIRE((fpid = fork()) != -1);
+ if (fpid == 0) {
+ trace_me();
+ exec_thread(NULL);
+ }
+
+ /* The first wait() should report the stop from SIGSTOP. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
+
+ events = PTRACE_EXEC;
+ ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* The next event should be for the child process's exec. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) ==
+ (PL_FLAG_EXEC | PL_FLAG_SCX));
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* The last event should be for the child process's exit. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE(WEXITSTATUS(status) == 0);
+
+ wpid = wait(&status);
+ ATF_REQUIRE(wpid == -1);
+ ATF_REQUIRE(errno == ECHILD);
+}
+
+ATF_TC_WITHOUT_HEAD(ptrace__event_mask);
+ATF_TC_BODY(ptrace__event_mask, tc)
+{
+ pid_t fpid, wpid;
+ int events, status;
+
+ ATF_REQUIRE((fpid = fork()) != -1);
+ if (fpid == 0) {
+ trace_me();
+ exit(0);
+ }
+
+ /* The first wait() should report the stop from SIGSTOP. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
+
+ /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */
+ ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1);
+ ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+ ATF_REQUIRE(events & PTRACE_FORK);
+ ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1);
+ ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+ ATF_REQUIRE(!(events & PTRACE_FORK));
+
+ /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */
+ ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1);
+ ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+ ATF_REQUIRE(events & PTRACE_LWP);
+ ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1);
+ ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events,
+ sizeof(events)) == 0);
+ ATF_REQUIRE(!(events & PTRACE_LWP));
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /* Should get one event at exit. */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE(WEXITSTATUS(status) == 0);
+
+ wpid = wait(&status);
+ ATF_REQUIRE(wpid == -1);
+ ATF_REQUIRE(errno == ECHILD);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -1376,6 +1570,10 @@
ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread);
ATF_TP_ADD_TC(tp, ptrace__lwp_events);
ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec);
+ ATF_TP_ADD_TC(tp, ptrace__siginfo);
+ ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable);
+ ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable);
+ ATF_TP_ADD_TC(tp, ptrace__event_mask);
return (atf_no_error());
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 2, 4:44 PM (5 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30730105
Default Alt Text
D7044.id18218.diff (17 KB)
Attached To
Mode
D7044: Add a mask of optional ptrace() events.
Attached
Detach File
Event Timeline
Log In to Comment