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 *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to