Print this page
Test of DTrace assert probes

@@ -38,28 +38,59 @@
 
 #include <sys/isa_defs.h>
 #include <sys/types.h>
 #include <sys/note.h>
 
+#ifdef KEBE
+#include <sys/sdt.h>
+#endif  /* KEBE */
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 /*
  * ASSERT(ex) causes a panic or debugger entry if expression ex is not
  * true.  ASSERT() is included only for debugging, and is a no-op in
  * production kernels.  VERIFY(ex), on the other hand, behaves like
  * ASSERT and is evaluated on both debug and non-debug kernels.
+ *
+ * KEBE SAYS if "KEBE" is defined on a non-DEBUG kernel, the ASSERT() will
+ * form an SDT probe of the form sdt:module:function:assert-<lineno>, with
+ * probe arguments:
+ *
+ * arg0 -> file name
+ * arg1 -> line number
+ * arg2 -> EX
  */
 
+#ifdef KEBE
+/* XXX KEBE HOPES that __LINE__ evaluates the same, but isn't sure. */
+#define ASSERTDTSTRBASE(x, y)   x ## y
+#define ASSERTDTSTR(x, y)       ASSERTDTSTRBASE(x, y)
+#define ASSERTDT(EX)    do { \
+        extern void ASSERTDTSTR(__dtrace_probe_assert__, __LINE__)(uintptr_t, \
+            uintptr_t, uintptr_t);                                      \
+        if (!(EX))                                                      \
+                ASSERTDTSTR(__dtrace_probe_assert__, __LINE__)          \
+                    ((uintptr_t)__FILE__,                               \
+                    (uintptr_t)__LINE__, (uintptr_t)#EX);               \
+_NOTE(CONSTCOND) } while (0)
+#endif  /* KEBE */
+
+
 extern int assfail(const char *, const char *, int);
 #define VERIFY(EX) ((void)((EX) || assfail(#EX, __FILE__, __LINE__)))
 #if DEBUG
 #define ASSERT(EX) ((void)((EX) || assfail(#EX, __FILE__, __LINE__)))
 #else
+#ifdef KEBE
+#define ASSERT(EX)      ASSERTDT(EX)
+#else
 #define ASSERT(x)  ((void)0)
-#endif
+#endif /* KEBE */
+#endif /* DEBUG */
 
 /*
  * Assertion variants sensitive to the compilation data model
  */
 #if defined(_LP64)

@@ -97,10 +128,39 @@
  * for unsigned, and ASSERT3P() is for pointers.  The VERIFY3*() macros
  * have the same relationship as above.
  */
 extern void assfail3(const char *, uintmax_t, const char *, uintmax_t,
     const char *, int);
+
+#ifdef KEBE
+/*
+ * KEBE SAYS, for the sdt:module:function:assert3-<lineno> will have more
+ * probe arguments:
+ *
+ * arg0 -> file name
+ * arg1 -> line number
+ * arg2 -> EX
+ * arg3 -> "left" boolean
+ * arg4 -> "OP" string
+ * arg5 -> "right" boolean
+ */
+#define KEBE3_IMPL(LEFT, OP, RIGHT, TYPE)       do { \
+        extern void ASSERTDTSTR(__dtrace_probe_assert3__, __LINE__)(   \
+            uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t,      \
+            uintptr_t);                                                 \
+        const TYPE __left = (TYPE)(LEFT);                               \
+        const TYPE __right = (TYPE)(RIGHT);                             \
+        if (!(__left OP __right))                                       \
+                ASSERTDTSTR(__dtrace_probe_assert3__, __LINE__)         \
+                    ((uintptr_t)__FILE__,                               \
+                    (uintptr_t)__LINE__,                                \
+                    (uintptr_t)(#LEFT " " #OP " " #RIGHT),              \
+                    (uintptr_t)__left, (uintptr_t)#OP,                  \
+                    (uintptr_t)__right);                                \
+_NOTE(CONSTCOND) } while (0)
+#endif  /* KEBE */
+
 #define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) do { \
         const TYPE __left = (TYPE)(LEFT); \
         const TYPE __right = (TYPE)(RIGHT); \
         if (!(__left OP __right)) \
                 assfail3(#LEFT " " #OP " " #RIGHT, \

@@ -117,14 +177,21 @@
 #define ASSERT3S(x, y, z)       VERIFY3_IMPL(x, y, z, int64_t)
 #define ASSERT3U(x, y, z)       VERIFY3_IMPL(x, y, z, uint64_t)
 #define ASSERT3P(x, y, z)       VERIFY3_IMPL(x, y, z, uintptr_t)
 #define ASSERT0(x)              VERIFY3_IMPL(x, ==, 0, uintmax_t)
 #else
+#ifdef KEBE
+#define ASSERT3S(x, y, z)       KEBE3_IMPL(x, y, z, int64_t)
+#define ASSERT3U(x, y, z)       KEBE3_IMPL(x, y, z, uint64_t)
+#define ASSERT3P(x, y, z)       KEBE3_IMPL(x, y, z, uintptr_t)
+#define ASSERT0(x)              KEBE3_IMPL(x, ==, 0, uintmax_t)
+#else
 #define ASSERT3S(x, y, z)       ((void)0)
 #define ASSERT3U(x, y, z)       ((void)0)
 #define ASSERT3P(x, y, z)       ((void)0)
 #define ASSERT0(x)              ((void)0)
+#endif /* KEBE */
 #endif
 
 /*
  * Compile-time assertion. The condition 'x' must be constant.
  */