svn commit: r219042 - in head/sys: kern sys

Dmitry Chagin dchagin at FreeBSD.org
Fri Feb 25 22:05:34 UTC 2011


Author: dchagin
Date: Fri Feb 25 22:05:33 2011
New Revision: 219042
URL: http://svn.freebsd.org/changeset/base/219042

Log:
  Introduce preliminary support of the show description of the ABI of
  traced process by adding two new events which records value of process
  sv_flags to the trace file at process creation/execing/exiting time.
  
  MFC after:	1 Month.

Modified:
  head/sys/kern/kern_exec.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_ktrace.c
  head/sys/sys/ktrace.h

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c	Fri Feb 25 22:03:28 2011	(r219041)
+++ head/sys/kern/kern_exec.c	Fri Feb 25 22:05:33 2011	(r219042)
@@ -899,6 +899,12 @@ done2:
 		exit1(td, W_EXITCODE(0, SIGABRT));
 		/* NOT REACHED */
 	}
+
+#ifdef KTRACE
+	if (error == 0)
+		ktrprocctor(p);
+#endif
+
 	return (error);
 }
 

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c	Fri Feb 25 22:03:28 2011	(r219041)
+++ head/sys/kern/kern_fork.c	Fri Feb 25 22:05:33 2011	(r219042)
@@ -557,10 +557,6 @@ do_fork(struct thread *td, int flags, st
 
 	callout_init(&p2->p_itcallout, CALLOUT_MPSAFE);
 
-#ifdef KTRACE
-	ktrprocfork(p1, p2);
-#endif
-
 	/*
 	 * If PF_FORK is set, the child process inherits the
 	 * procfs ioctl flags from its parent.
@@ -596,6 +592,10 @@ do_fork(struct thread *td, int flags, st
 	p2->p_acflag = AFORK;
 	PROC_UNLOCK(p2);
 
+#ifdef KTRACE
+	ktrprocfork(p1, p2);
+#endif
+
 	/*
 	 * Finish creating the child process.  It will return via a different
 	 * execution path later.  (ie: directly into user mode)

Modified: head/sys/kern/kern_ktrace.c
==============================================================================
--- head/sys/kern/kern_ktrace.c	Fri Feb 25 22:03:28 2011	(r219041)
+++ head/sys/kern/kern_ktrace.c	Fri Feb 25 22:05:33 2011	(r219042)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/ktrace.h>
 #include <sys/sx.h>
 #include <sys/sysctl.h>
+#include <sys/sysent.h>
 #include <sys/syslog.h>
 #include <sys/sysproto.h>
 
@@ -93,6 +94,7 @@ struct ktr_request {
 	struct	ktr_header ktr_header;
 	void	*ktr_buffer;
 	union {
+		struct	ktr_proc_ctor ktr_proc_ctor;
 		struct	ktr_syscall ktr_syscall;
 		struct	ktr_sysret ktr_sysret;
 		struct	ktr_genio ktr_genio;
@@ -113,6 +115,8 @@ static int data_lengths[] = {
 	0,					/* KTR_USER */
 	0,					/* KTR_STRUCT */
 	0,					/* KTR_SYSCTL */
+	sizeof(struct ktr_proc_ctor),		/* KTR_PROCCTOR */
+	0,					/* KTR_PROCDTOR */
 };
 
 static STAILQ_HEAD(, ktr_request) ktr_free;
@@ -134,7 +138,9 @@ static struct sx ktrace_sx;
 static void ktrace_init(void *dummy);
 static int sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS);
 static u_int ktrace_resize_pool(u_int oldsize, u_int newsize);
+static struct ktr_request *ktr_getrequest_ne(struct thread *, int type);
 static struct ktr_request *ktr_getrequest(int type);
+static void ktr_submitrequest_ne(struct thread *td, struct ktr_request *req);
 static void ktr_submitrequest(struct thread *td, struct ktr_request *req);
 static void ktr_freeproc(struct proc *p, struct ucred **uc,
     struct vnode **vp);
@@ -144,6 +150,7 @@ static void ktr_writerequest(struct thre
 static int ktrcanset(struct thread *,struct proc *);
 static int ktrsetchildren(struct thread *,struct proc *,int,int,struct vnode *);
 static int ktrops(struct thread *,struct proc *,int,int,struct vnode *);
+static void ktrprocctor_ne(struct thread *, struct proc *p);
 
 /*
  * ktrace itself generates events, such as context switches, which we do not
@@ -265,18 +272,15 @@ CTASSERT(sizeof(((struct ktr_header *)NU
     (sizeof((struct thread *)NULL)->td_name));
 
 static struct ktr_request *
-ktr_getrequest(int type)
+ktr_getrequest_ne(struct thread *td, int type)
 {
 	struct ktr_request *req;
-	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
 	int pm;
 
-	ktrace_enter(td);	/* XXX: In caller instead? */
 	mtx_lock(&ktrace_mtx);
 	if (!KTRCHECK(td, type)) {
 		mtx_unlock(&ktrace_mtx);
-		ktrace_exit(td);
 		return (NULL);
 	}
 	req = STAILQ_FIRST(&ktr_free);
@@ -302,11 +306,24 @@ ktr_getrequest(int type)
 		mtx_unlock(&ktrace_mtx);
 		if (pm)
 			printf("Out of ktrace request objects.\n");
-		ktrace_exit(td);
 	}
 	return (req);
 }
 
+static struct ktr_request *
+ktr_getrequest(int type)
+{
+	struct thread *td = curthread;
+	struct ktr_request *req;
+
+	ktrace_enter(td);
+	req = ktr_getrequest_ne(td, type);
+	if (req == NULL)
+		ktrace_exit(td);
+
+	return (req);
+}
+
 /*
  * Some trace generation environments don't permit direct access to VFS,
  * such as during a context switch where sleeping is not allowed.  Under these
@@ -360,7 +377,7 @@ ktr_drain(struct thread *td)
  * been cached in the thread.
  */
 static void
-ktr_submitrequest(struct thread *td, struct ktr_request *req)
+ktr_submitrequest_ne(struct thread *td, struct ktr_request *req)
 {
 
 	ktrace_assert(td);
@@ -370,7 +387,14 @@ ktr_submitrequest(struct thread *td, str
 	ktr_writerequest(td, req);
 	ktr_freerequest(req);
 	sx_xunlock(&ktrace_sx);
+}
+
+static void
+ktr_submitrequest(struct thread *td, struct ktr_request *req)
+{
 
+	ktrace_assert(td);
+	ktr_submitrequest_ne(td, req);
 	ktrace_exit(td);
 }
 
@@ -488,6 +512,7 @@ ktrprocexec(struct proc *p, struct ucred
 void
 ktrprocexit(struct thread *td)
 {
+	struct ktr_request *req;
 	struct proc *p;
 	struct ucred *cred;
 	struct vnode *vp;
@@ -501,6 +526,9 @@ ktrprocexit(struct thread *td)
 	sx_xlock(&ktrace_sx);
 	ktr_drain(td);
 	sx_xunlock(&ktrace_sx);
+	req = ktr_getrequest_ne(td, KTR_PROCDTOR);
+	if (req != NULL)
+		ktr_submitrequest_ne(td, req);
 	PROC_LOCK(p);
 	mtx_lock(&ktrace_mtx);
 	ktr_freeproc(p, &cred, &vp);
@@ -516,6 +544,37 @@ ktrprocexit(struct thread *td)
 	ktrace_exit(td);
 }
 
+static void
+ktrprocctor_ne(struct thread *td, struct proc *p)
+{
+	struct ktr_proc_ctor *ktp;
+	struct ktr_request *req;
+	struct thread *td2;
+
+	ktrace_assert(td);
+	td2 = FIRST_THREAD_IN_PROC(p);
+	req = ktr_getrequest_ne(td2, KTR_PROCCTOR);
+	if (req == NULL)
+		return;
+
+	ktp = &req->ktr_data.ktr_proc_ctor;
+	ktp->sv_flags = p->p_sysent->sv_flags;
+	ktr_submitrequest_ne(td, req);
+}
+
+void
+ktrprocctor(struct proc *p)
+{
+	struct thread *td = curthread;
+
+	if ((p->p_traceflag & KTRFAC_MASK) == 0)
+		return;
+
+	ktrace_enter(td);
+	ktrprocctor_ne(td, p);
+	ktrace_exit(td);
+}
+
 /*
  * When a process forks, enable tracing in the new process if needed.
  */
@@ -523,8 +582,7 @@ void
 ktrprocfork(struct proc *p1, struct proc *p2)
 {
 
-	PROC_LOCK_ASSERT(p1, MA_OWNED);
-	PROC_LOCK_ASSERT(p2, MA_OWNED);
+	PROC_LOCK(p1);
 	mtx_lock(&ktrace_mtx);
 	KASSERT(p2->p_tracevp == NULL, ("new process has a ktrace vnode"));
 	if (p1->p_traceflag & KTRFAC_INHERIT) {
@@ -537,6 +595,9 @@ ktrprocfork(struct proc *p1, struct proc
 		}
 	}
 	mtx_unlock(&ktrace_mtx);
+	PROC_UNLOCK(p1);
+
+	ktrprocctor(p2);
 }
 
 /*
@@ -971,6 +1032,9 @@ ktrops(td, p, ops, facs, vp)
 	if (tracecred != NULL)
 		crfree(tracecred);
 
+	if ((p->p_traceflag & KTRFAC_MASK) != 0)
+		ktrprocctor_ne(td, p);
+
 	return (1);
 }
 

Modified: head/sys/sys/ktrace.h
==============================================================================
--- head/sys/sys/ktrace.h	Fri Feb 25 22:03:28 2011	(r219041)
+++ head/sys/sys/ktrace.h	Fri Feb 25 22:05:33 2011	(r219042)
@@ -156,6 +156,7 @@ struct ktr_csw {
 	 */
 struct sockaddr;
 struct stat;
+struct sysentvec;
 
 /*
  * KTR_SYSCTL - name of a sysctl MIB
@@ -164,6 +165,19 @@ struct stat;
 	/* record contains null-terminated MIB name */
 
 /*
+ * KTR_PROCCTOR - trace process creation (multiple ABI support)
+ */
+#define KTR_PROCCTOR	10
+struct ktr_proc_ctor {
+	u_int	sv_flags;	/* struct sysentvec sv_flags copy */
+};
+
+/*
+ * KTR_PROCDTOR - trace process destruction (multiple ABI support)
+ */
+#define KTR_PROCDTOR	11
+
+/*
  * KTR_DROP - If this bit is set in ktr_type, then at least one event
  * between the previous record and this record was dropped.
  */
@@ -182,6 +196,8 @@ struct stat;
 #define KTRFAC_USER	(1<<KTR_USER)
 #define KTRFAC_STRUCT	(1<<KTR_STRUCT)
 #define KTRFAC_SYSCTL	(1<<KTR_SYSCTL)
+#define KTRFAC_PROCCTOR	(1<<KTR_PROCCTOR)
+#define KTRFAC_PROCDTOR	(1<<KTR_PROCDTOR)
 
 /*
  * trace flags (also in p_traceflags)
@@ -198,6 +214,7 @@ void	ktrgenio(int, enum uio_rw, struct u
 void	ktrsyscall(int, int narg, register_t args[]);
 void	ktrsysctl(int *name, u_int namelen);
 void	ktrsysret(int, int, register_t);
+void	ktrprocctor(struct proc *);
 void	ktrprocexec(struct proc *, struct ucred **, struct vnode **);
 void	ktrprocexit(struct thread *);
 void	ktrprocfork(struct proc *, struct proc *);


More information about the svn-src-all mailing list