Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Oct 2015 01:27:45 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r289780 - in stable: 10/lib/libc/sys 10/sys/kern 10/sys/sys 10/tests/sys/kern 9/lib/libc/sys 9/sys/kern 9/sys/sys
Message-ID:  <201510230127.t9N1RjQE048161@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Oct 23 01:27:44 2015
New Revision: 289780
URL: https://svnweb.freebsd.org/changeset/base/289780

Log:
  MFC 287386,288949,288993:
  Export current system call code and argument count for system call entry
  and exit events.  To preserve the ABI, the new fields are moved to the
  end of struct thread in these branches (unlike HEAD) and explicitly copied
  when new threads are created.  In addition, the new tests are only added
  in 10.
  
  r287386:
  Export current system call code and argument count for system call entry
  and exit events. procfs stop events for system call tracing report these
  values (argument count for system call entry and code for system call exit),
  but ptrace() does not provide this information. (Note that while the system
  call code can be determined in an ABI-specific manner during system call
  entry, it is not generally available during system call exit.)
  
  The values are exported via new fields at the end of struct ptrace_lwpinfo
  available via PT_LWPINFO.
  
  r288949:
  Fix various edge cases related to system call tracing.
  - Always set td_dbg_sc_* when P_TRACED is set on system call entry
    even if the debugger is not tracing system call entries.  This
    ensures the fields are valid when reporting other stops that
    occur at system call boundaries such as for PT_FOLLOW_FORKS or
    when only tracing system call exits.
  - Set TDB_SCX when reporting the stop for a new child process in
    fork_return().  This causes the event to be reported as a system
    call exit.
  - Report a system call exit event in fork_return() for new threads in
    a traced process.
  - Copy td_dbg_sc_* to new threads instead of zeroing.  This ensures
    that td_dbg_sc_code in particular will report the system call that
    created the new thread or process when it reports a system call
    exit event in fork_return().
  - Add new ptrace tests to verify that new child processes and threads
    report system call exit events with a valid pl_syscall_code via
    PT_LWPINFO.
  
  r288993:
  Document the recently added pl_syscall_* fields in struct ptrace_lwpinfo.

Modified:
  stable/9/lib/libc/sys/ptrace.2
  stable/9/sys/kern/kern_fork.c
  stable/9/sys/kern/kern_thr.c
  stable/9/sys/kern/subr_syscall.c
  stable/9/sys/kern/sys_process.c
  stable/9/sys/sys/proc.h
  stable/9/sys/sys/ptrace.h
Directory Properties:
  stable/9/lib/libc/   (props changed)
  stable/9/lib/libc/sys/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/sys/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/10/lib/libc/sys/ptrace.2
  stable/10/sys/kern/kern_fork.c
  stable/10/sys/kern/kern_thr.c
  stable/10/sys/kern/subr_syscall.c
  stable/10/sys/kern/sys_process.c
  stable/10/sys/sys/proc.h
  stable/10/sys/sys/ptrace.h
  stable/10/tests/sys/kern/Makefile
  stable/10/tests/sys/kern/ptrace_test.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/9/lib/libc/sys/ptrace.2
==============================================================================
--- stable/9/lib/libc/sys/ptrace.2	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/lib/libc/sys/ptrace.2	Fri Oct 23 01:27:44 2015	(r289780)
@@ -2,7 +2,7 @@
 .\"	$NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
 .\"
 .\" This file is in the public domain.
-.Dd February 7, 2013
+.Dd October 6, 2015
 .Dt PTRACE 2
 .Os
 .Sh NAME
@@ -307,6 +307,8 @@ struct ptrace_lwpinfo {
 	siginfo_t pl_siginfo;
 	char	pl_tdname[MAXCOMLEN + 1];
 	int	pl_child_pid;
+	u_int	pl_syscall_code;
+	u_int	pl_syscall_narg;
 };
 .Ed
 .Pp
@@ -395,6 +397,27 @@ stop when
 .Dv PL_FLAG_FORKED
 is set in
 .Va pl_flags .
+.It pl_syscall_code
+The ABI-specific identifier of the current system call.
+Note that for indirect system calls this field reports the indirected
+system call.
+Only valid when
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+is set in
+.Va pl_flags.
+.It pl_syscall_narg
+The number of arguments passed to the current system call not counting
+the system call identifier.
+Note that for indirect system calls this field reports the arguments
+passed to the indirected system call.
+Only valid when
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+is set in
+.Va pl_flags.
 .El
 .It PT_GETNUMLWPS
 This request returns the number of kernel threads associated with the

Modified: stable/9/sys/kern/kern_fork.c
==============================================================================
--- stable/9/sys/kern/kern_fork.c	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/kern/kern_fork.c	Fri Oct 23 01:27:44 2015	(r289780)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/procdesc.h>
 #include <sys/pioctl.h>
+#include <sys/ptrace.h>
 #include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/sched.h>
@@ -477,6 +478,8 @@ do_fork(struct thread *td, int flags, st
 	td2->td_sigmask = td->td_sigmask;
 	td2->td_flags = TDF_INMEM;
 	td2->td_lend_user_pri = PRI_MAX;
+	td2->td_dbg_sc_code = td->td_dbg_sc_code;
+	td2->td_dbg_sc_narg = td->td_dbg_sc_narg;
 
 #ifdef VIMAGE
 	td2->td_vnet = NULL;
@@ -1022,8 +1025,8 @@ fork_return(struct thread *td, struct tr
 {
 	struct proc *p, *dbg;
 
+	p = td->td_proc;
 	if (td->td_dbgflags & TDB_STOPATFORK) {
-		p = td->td_proc;
 		sx_xlock(&proctree_lock);
 		PROC_LOCK(p);
 		if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) ==
@@ -1040,9 +1043,9 @@ fork_return(struct thread *td, struct tr
 			    p->p_pid, p->p_oppid);
 			proc_reparent(p, dbg);
 			sx_xunlock(&proctree_lock);
-			td->td_dbgflags |= TDB_CHILD;
+			td->td_dbgflags |= TDB_CHILD | TDB_SCX;
 			ptracestop(td, SIGSTOP);
-			td->td_dbgflags &= ~TDB_CHILD;
+			td->td_dbgflags &= ~(TDB_CHILD | TDB_SCX);
 		} else {
 			/*
 			 * ... otherwise clear the request.
@@ -1052,6 +1055,18 @@ fork_return(struct thread *td, struct tr
 			cv_broadcast(&p->p_dbgwait);
 		}
 		PROC_UNLOCK(p);
+	} else if (p->p_flag & P_TRACED) {
+ 		/*
+		 * This is the start of a new thread in a traced
+		 * process.  Report a system call exit event.
+		 */
+		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)
+			ptracestop(td, SIGTRAP);
+		td->td_dbgflags &= ~TDB_SCX;
+		PROC_UNLOCK(p);
 	}
 
 	userret(td, frame);

Modified: stable/9/sys/kern/kern_thr.c
==============================================================================
--- stable/9/sys/kern/kern_thr.c	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/kern/kern_thr.c	Fri Oct 23 01:27:44 2015	(r289780)
@@ -227,6 +227,8 @@ create_thread(struct thread *td, mcontex
 	    __rangeof(struct thread, td_startcopy, td_endcopy));
 	newtd->td_proc = td->td_proc;
 	newtd->td_ucred = crhold(td->td_ucred);
+	newtd->td_dbg_sc_code = td->td_dbg_sc_code;
+	newtd->td_dbg_sc_narg = td->td_dbg_sc_narg;
 
 	if (ctx != NULL) { /* old way to set user context */
 		error = set_mcontext(newtd, ctx);

Modified: stable/9/sys/kern/subr_syscall.c
==============================================================================
--- stable/9/sys/kern/subr_syscall.c	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/kern/subr_syscall.c	Fri Oct 23 01:27:44 2015	(r289780)
@@ -85,9 +85,12 @@ syscallenter(struct thread *td, struct s
 
 	if (error == 0) {
 		STOPEVENT(p, S_SCE, sa->narg);
-		if (p->p_flag & P_TRACED && p->p_stops & S_PT_SCE) {
+		if (p->p_flag & P_TRACED) {
 			PROC_LOCK(p);
-			ptracestop((td), SIGTRAP);
+			td->td_dbg_sc_code = sa->code;
+			td->td_dbg_sc_narg = sa->narg;
+			if (p->p_stops & S_PT_SCE)
+				ptracestop((td), SIGTRAP);
 			PROC_UNLOCK(p);
 		}
 		if (td->td_dbgflags & TDB_USERWR) {
@@ -96,6 +99,10 @@ syscallenter(struct thread *td, struct s
 			 * debugger modified registers or memory.
 			 */
 			error = (p->p_sysent->sv_fetch_syscall_args)(td, sa);
+			PROC_LOCK(p);
+			td->td_dbg_sc_code = sa->code;
+			td->td_dbg_sc_narg = sa->narg;
+			PROC_UNLOCK(p);
 #ifdef KTRACE
 			if (KTRPOINT(td, KTR_SYSCALL))
 				ktrsyscall(sa->code, sa->narg, sa->args);

Modified: stable/9/sys/kern/sys_process.c
==============================================================================
--- stable/9/sys/kern/sys_process.c	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/kern/sys_process.c	Fri Oct 23 01:27:44 2015	(r289780)
@@ -97,6 +97,8 @@ struct ptrace_lwpinfo32 {
 	struct siginfo32 pl_siginfo;	/* siginfo for signal */
 	char	pl_tdname[MAXCOMLEN + 1];	/* LWP name. */
 	int	pl_child_pid;		/* New child pid */
+	u_int		pl_syscall_code;
+	u_int		pl_syscall_narg;
 };
 
 #endif
@@ -483,6 +485,8 @@ ptrace_lwpinfo_to32(const struct ptrace_
 	siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
 	strcpy(pl32->pl_tdname, pl->pl_tdname);
 	pl32->pl_child_pid = pl->pl_child_pid;
+	pl32->pl_syscall_code = pl->pl_syscall_code;
+	pl32->pl_syscall_narg = pl->pl_syscall_narg;
 }
 #endif /* COMPAT_FREEBSD32 */
 
@@ -1212,6 +1216,13 @@ kern_ptrace(struct thread *td, int req, 
 		pl->pl_sigmask = td2->td_sigmask;
 		pl->pl_siglist = td2->td_siglist;
 		strcpy(pl->pl_tdname, td2->td_name);
+		if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) != 0) {
+			pl->pl_syscall_code = td2->td_dbg_sc_code;
+			pl->pl_syscall_narg = td2->td_dbg_sc_narg;
+		} else {
+			pl->pl_syscall_code = 0;
+			pl->pl_syscall_narg = 0;
+		}
 #ifdef COMPAT_FREEBSD32
 		if (wrap32)
 			ptrace_lwpinfo_to32(pl, pl32);

Modified: stable/9/sys/sys/proc.h
==============================================================================
--- stable/9/sys/sys/proc.h	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/sys/proc.h	Fri Oct 23 01:27:44 2015	(r289780)
@@ -170,6 +170,7 @@ struct procdesc;
 struct racct;
 struct sbuf;
 struct sleepqueue;
+struct syscall_args;
 struct td_sched;
 struct thread;
 struct trapframe;
@@ -317,6 +318,8 @@ struct thread {
 	int		td_ma_cnt;	/* (k) size of *td_ma */
 	struct rl_q_entry *td_rlqe;	/* (k) Associated range lock entry. */
 	u_int		td_vp_reserv;	/* (k) Count of reserved vnodes. */
+	u_int		td_dbg_sc_code;	/* (c) Syscall code to debugger. */
+	u_int		td_dbg_sc_narg;	/* (c) Syscall arg count to debugger.*/
 };
 
 struct mtx *thread_lock_block(struct thread *);
@@ -927,7 +930,6 @@ void	userret(struct thread *, struct tra
 
 void	cpu_exit(struct thread *);
 void	exit1(struct thread *, int) __dead2;
-struct syscall_args;
 int	cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
 void	cpu_fork(struct thread *, struct proc *, struct thread *, int);
 void	cpu_set_fork_handler(struct thread *, void (*)(void *), void *);

Modified: stable/9/sys/sys/ptrace.h
==============================================================================
--- stable/9/sys/sys/ptrace.h	Fri Oct 23 00:48:00 2015	(r289779)
+++ stable/9/sys/sys/ptrace.h	Fri Oct 23 01:27:44 2015	(r289780)
@@ -113,6 +113,8 @@ struct ptrace_lwpinfo {
 	struct __siginfo pl_siginfo;	/* siginfo for signal */
 	char		pl_tdname[MAXCOMLEN + 1]; /* LWP name */
 	int		pl_child_pid;	/* New child pid */
+	u_int		pl_syscall_code;
+	u_int		pl_syscall_narg;
 };
 
 /* Argument structure for PT_VM_ENTRY. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510230127.t9N1RjQE048161>