Author: markj
Date: Tue Apr 10 13:47:09 2018
New Revision: 332364
URL: https://svnweb.freebsd.org/changeset/base/332364

Log:
  Assert that dtrace_probe() doesn't re-enter itself.
  
  This helps catch cases where an instrumented function is called while
  in probe context.
  
  Submitted by: Domagoj Stolfa <domagoj.sto...@gmail.com>
  MFC after:    2 weeks
  Sponsored by: DARPA/AFRL
  Differential Revision:        https://reviews.freebsd.org/D14863

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  head/sys/cddl/dev/dtrace/dtrace_cddl.h

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Tue Apr 
10 13:35:07 2018        (r332363)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Tue Apr 
10 13:47:09 2018        (r332364)
@@ -7257,6 +7257,44 @@ dtrace_store_by_ref(dtrace_difo_t *dp, caddr_t tomax, 
 }
 
 /*
+ * Disables interrupts and sets the per-thread inprobe flag. When DEBUG is
+ * defined, we also assert that we are not recursing unless the probe ID is an
+ * error probe.
+ */
+static dtrace_icookie_t
+dtrace_probe_enter(dtrace_id_t id)
+{
+       dtrace_icookie_t cookie;
+
+       cookie = dtrace_interrupt_disable();
+
+       /*
+        * Unless this is an ERROR probe, we are not allowed to recurse in
+        * dtrace_probe(). Recursing into DTrace probe usually means that a
+        * function is instrumented that should not have been instrumented or
+        * that the ordering guarantee of the records will be violated,
+        * resulting in unexpected output. If there is an exception to this
+        * assertion, a new case should be added.
+        */
+       ASSERT(curthread->t_dtrace_inprobe == 0 ||
+           id == dtrace_probeid_error);
+       curthread->t_dtrace_inprobe = 1;
+
+       return (cookie);
+}
+
+/*
+ * Disables interrupts and clears the per-thread inprobe flag.
+ */
+static void
+dtrace_probe_exit(dtrace_icookie_t cookie)
+{
+
+       curthread->t_dtrace_inprobe = 0;
+       dtrace_interrupt_enable(cookie);
+}
+
+/*
  * If you're looking for the epicenter of DTrace, you just found it.  This
  * is the function called by the provider to fire a probe -- from which all
  * subsequent probe-context DTrace activity emanates.
@@ -7290,7 +7328,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t
                return;
 #endif
 
-       cookie = dtrace_interrupt_disable();
+       cookie = dtrace_probe_enter(id);
        probe = dtrace_probes[id - 1];
        cpuid = curcpu;
        onintr = CPU_ON_INTR(CPU);
@@ -7301,7 +7339,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t
                 * We have hit in the predicate cache; we know that
                 * this predicate would evaluate to be false.
                 */
-               dtrace_interrupt_enable(cookie);
+               dtrace_probe_exit(cookie);
                return;
        }
 
@@ -7313,7 +7351,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t
                /*
                 * We don't trace anything if we're panicking.
                 */
-               dtrace_interrupt_enable(cookie);
+               dtrace_probe_exit(cookie);
                return;
        }
 
@@ -7939,7 +7977,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t
        if (vtime)
                curthread->t_dtrace_start = dtrace_gethrtime();
 
-       dtrace_interrupt_enable(cookie);
+       dtrace_probe_exit(cookie);
 }
 
 /*

Modified: head/sys/cddl/dev/dtrace/dtrace_cddl.h
==============================================================================
--- head/sys/cddl/dev/dtrace/dtrace_cddl.h      Tue Apr 10 13:35:07 2018        
(r332363)
+++ head/sys/cddl/dev/dtrace/dtrace_cddl.h      Tue Apr 10 13:47:09 2018        
(r332364)
@@ -46,6 +46,7 @@ typedef struct kdtrace_proc {
 typedef struct kdtrace_thread {
        u_int8_t        td_dtrace_stop; /* Indicates a DTrace-desired stop */
        u_int8_t        td_dtrace_sig;  /* Signal sent via DTrace's raise() */
+       u_int8_t        td_dtrace_inprobe; /* Are we in a probe? */
        u_int           td_predcache;   /* DTrace predicate cache */
        u_int64_t       td_dtrace_vtime; /* DTrace virtual time */
        u_int64_t       td_dtrace_start; /* DTrace slice start time */
@@ -97,6 +98,7 @@ typedef struct kdtrace_thread {
 #define        t_dtrace_start  td_dtrace->td_dtrace_start
 #define        t_dtrace_stop   td_dtrace->td_dtrace_stop
 #define        t_dtrace_sig    td_dtrace->td_dtrace_sig
+#define        t_dtrace_inprobe        td_dtrace->td_dtrace_inprobe
 #define        t_predcache     td_dtrace->td_predcache
 #define        t_dtrace_ft     td_dtrace->td_dtrace_ft
 #define        t_dtrace_on     td_dtrace->td_dtrace_on
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to