On Friday 12 March 2010 01:32 pm, Jung-uk Kim wrote:
> On Friday 12 March 2010 04:29 am, Kostik Belousov wrote:
> > On Thu, Mar 11, 2010 at 06:15:07PM -0500, Jung-uk Kim wrote:
> > > On Thursday 11 March 2010 04:55 pm, Marcel Moolenaar wrote:
> > > > On Mar 11, 2010, at 1:24 PM, Jung-uk Kim wrote:
> > > > > While I was debugging syscalls, I found a very useful field
> > > > > in struct thread, td_errno.  It seems it was added for
> > > > > dtrace but it is only populated on amd64 and i386.  Is the
> > > > > attached patch acceptable for maintainers of other
> > > > > platforms?
> > > >
> > > > Isn't it better to do it in cpu_set_syscall_retval()?
> > > > That way you catch all cases, plus you can save the
> > > > translated error as well...
> > >
> > > I just took amd64/i386 as an example and I was not sure whether
> > > it was meant to store translated error or not.  Does anyone
> > > with DTrace internal knowledge answer the question?
> >
> > I do not know that much about DTrace, but it seems that setting
> > td_errno in cpu_set_syscall_retval() is too late. Dtrace has a
> > probe after the syscall return, and it is called right before
> > cpu_set_syscall_retval() can be reasonably called. The probe only
> > issued for syscall that goes into sysent.
>
> Ah, I can see that now.  So, if/when we implement DTrace SYSCALL
> provider for other arches, this is the right place. :-)

I went ahead and implemented DTrace SYSCALL providers for non-x86 
arches.  It passes 'make universe' test but I don't know if it works.  
Can maintainers of other arches test or review the attached patch?

Thanks!

Jung-uk Kim
Index: sys/arm/arm/trap.c
===================================================================
--- sys/arm/arm/trap.c  (revision 205172)
+++ sys/arm/arm/trap.c  (working copy)
@@ -122,7 +122,18 @@ __FBSDID("$FreeBSD$");
 #include <sys/kdb.h>
 #endif
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
 
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
+
 void swi_handler(trapframe_t *);
 void undefinedinstruction(trapframe_t *);
 
@@ -925,9 +936,36 @@ syscall(struct thread *td, trapframe_t *frame, u_i
                td->td_retval[1] = 0;
                STOPEVENT(p, S_SCE, callp->sy_narg);
                PTRACESTOP_SC(p, td, S_PT_SCE);
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, args);
                AUDIT_SYSCALL_EXIT(error, td);
+
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                KASSERT(td->td_ar == NULL, 
                    ("returning from syscall with td_ar set!"));
        }
Index: sys/powerpc/booke/trap.c
===================================================================
--- sys/powerpc/booke/trap.c    (revision 205172)
+++ sys/powerpc/booke/trap.c    (working copy)
@@ -75,6 +75,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/trap.h>
 #include <machine/spr.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 #ifdef FPU_EMU
 #include <powerpc/fpu/fpu_extern.h>
 #endif
@@ -409,10 +420,35 @@ syscall(struct trapframe *frame)
 
                PTRACESTOP_SC(p, td, S_PT_SCE);
 
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, params);
                AUDIT_SYSCALL_EXIT(error, td);
 
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", p->p_comm,
                     syscallnames[code], td->td_retval[0]);
        }
Index: sys/powerpc/aim/trap.c
===================================================================
--- sys/powerpc/aim/trap.c      (revision 205172)
+++ sys/powerpc/aim/trap.c      (working copy)
@@ -77,6 +77,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/spr.h>
 #include <machine/sr.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 static void    trap_fatal(struct trapframe *frame);
 static void    printtrap(u_int vector, struct trapframe *frame, int isfatal,
                    int user);
@@ -405,10 +416,35 @@ syscall(struct trapframe *frame)
 
                PTRACESTOP_SC(p, td, S_PT_SCE);
 
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, params);
                AUDIT_SYSCALL_EXIT(error, td);
 
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", td->td_name,
                     syscallnames[code], td->td_retval[0]);
        }
Index: sys/sparc64/sparc64/trap.c
===================================================================
--- sys/sparc64/sparc64/trap.c  (revision 205172)
+++ sys/sparc64/sparc64/trap.c  (working copy)
@@ -94,6 +94,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/tsb.h>
 #include <machine/watch.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 struct syscall_args {
        u_long code;
        struct sysent *callp;
@@ -648,10 +659,35 @@ syscall(struct trapframe *tf)
                        td->td_retval[1] = 0;
                }
 
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(sa.code, td);
                error = (*sa.callp->sy_call)(td, sa.argp);
                AUDIT_SYSCALL_EXIT(error, td);
 
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx",
                    p, error, syscallnames[sa.code], td->td_retval[0],
                    td->td_retval[1]);
Index: sys/ia64/ia64/trap.c
===================================================================
--- sys/ia64/ia64/trap.c        (revision 205172)
+++ sys/ia64/ia64/trap.c        (working copy)
@@ -76,6 +76,17 @@ __FBSDID("$FreeBSD$");
 
 #include <ia64/disasm/disasm.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 static int print_usertrap = 0;
 SYSCTL_INT(_machdep, OID_AUTO, print_usertrap,
     CTLFLAG_RW, &print_usertrap, 0, "");
@@ -970,10 +981,35 @@ syscall(struct trapframe *tf)
 
        PTRACESTOP_SC(p, td, S_PT_SCE);
 
+#ifdef KDTRACE_HOOKS
+       /*
+        * If the systrace module has registered it's probe
+        * callback and if there is a probe active for the
+        * syscall 'entry', process the probe.
+        */
+       if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+               (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                   sa.callp, sa.args);
+#endif
+
        AUDIT_SYSCALL_ENTER(code, td);
        error = (*callp->sy_call)(td, args);
        AUDIT_SYSCALL_EXIT(error, td);
 
+       /* Save the latest error return value. */
+       td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+       /*
+        * If the systrace module has registered it's probe
+        * callback and if there is a probe active for the
+        * syscall 'return', process the probe.
+        */
+       if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+               (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                   sa.callp, sa.args);
+#endif
+
        cpu_set_syscall_retval(td, error);
        td->td_syscalls++;
 
Index: sys/ia64/ia32/ia32_trap.c
===================================================================
--- sys/ia64/ia32/ia32_trap.c   (revision 205172)
+++ sys/ia64/ia32/ia32_trap.c   (working copy)
@@ -48,6 +48,17 @@ __FBSDID("$FreeBSD$");
 
 #include <security/audit/audit.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 extern char *syscallnames[];
 
 static void
@@ -124,9 +135,34 @@ ia32_syscall(struct trapframe *tf)
 
                PTRACESTOP_SC(p, td, S_PT_SCE);
 
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, args64);
                AUDIT_SYSCALL_EXIT(error, td);
+
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
        }
 
        switch (error) {
Index: sys/sun4v/sun4v/trap.c
===================================================================
--- sys/sun4v/sun4v/trap.c      (revision 205172)
+++ sys/sun4v/sun4v/trap.c      (working copy)
@@ -96,6 +96,17 @@
 
 #include <security/audit/audit.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the systrace module
+ * when it is loaded. This keeps the DTrace syscall provider
+ * implementation opaque. 
+ */
+systrace_probe_func_t  systrace_probe_func;
+#endif
+
 void trap(struct trapframe *tf, int64_t type, uint64_t data);
 void syscall(struct trapframe *tf);
 
@@ -662,10 +673,35 @@ syscall(struct trapframe *tf)
 
                PTRACESTOP_SC(p, td, S_PT_SCE);
 
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'entry', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
+                       (*systrace_probe_func)(sa.callp->sy_entry, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, argp);
                AUDIT_SYSCALL_EXIT(error, td);
 
+               /* Save the latest error return value. */
+               td->td_errno = error;
+
+#ifdef KDTRACE_HOOKS
+               /*
+                * If the systrace module has registered it's probe
+                * callback and if there is a probe active for the
+                * syscall 'return', process the probe.
+                */
+               if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
+                       (*systrace_probe_func)(sa.callp->sy_return, sa.code,
+                           sa.callp, sa.args);
+#endif
+
                CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
                    error, syscallnames[code], td->td_retval[0],
                    td->td_retval[1]);
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to