Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -7291,6 +7291,20 @@ #endif cookie = dtrace_interrupt_disable(); + /* + * NOTE: This check is not performed if DEBUG is not defined. + * + * 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_wouldrecurse == 0 || + id == dtrace_probeid_error); + curthread->t_dtrace_wouldrecurse = 1; + probe = dtrace_probes[id - 1]; cpuid = curcpu; onintr = CPU_ON_INTR(CPU); @@ -7301,6 +7315,7 @@ * We have hit in the predicate cache; we know that * this predicate would evaluate to be false. */ + curthread->t_dtrace_wouldrecurse = 0; dtrace_interrupt_enable(cookie); return; } @@ -7313,6 +7328,7 @@ /* * We don't trace anything if we're panicking. */ + curthread->t_dtrace_wouldrecurse = 0; dtrace_interrupt_enable(cookie); return; } @@ -7939,6 +7955,7 @@ if (vtime) curthread->t_dtrace_start = dtrace_gethrtime(); + curthread->t_dtrace_wouldrecurse = 0; dtrace_interrupt_enable(cookie); } Index: sys/cddl/dev/dtrace/dtrace_cddl.h =================================================================== --- sys/cddl/dev/dtrace/dtrace_cddl.h +++ sys/cddl/dev/dtrace/dtrace_cddl.h @@ -63,15 +63,18 @@ #ifdef __amd64__ u_int8_t _td_dtrace_reg; #endif + u_int8_t _td_dtrace_wouldrecurse; + /* Are we recursing dtrace_probe()? */ } _tds; u_long _td_dtrace_ft; /* Bitwise or of these flags. */ } _tdu; -#define td_dtrace_ft _tdu._td_dtrace_ft -#define td_dtrace_on _tdu._tds._td_dtrace_on -#define td_dtrace_step _tdu._tds._td_dtrace_step -#define td_dtrace_ret _tdu._tds._td_dtrace_ret -#define td_dtrace_ast _tdu._tds._td_dtrace_ast -#define td_dtrace_reg _tdu._tds._td_dtrace_reg +#define td_dtrace_ft _tdu._td_dtrace_ft +#define td_dtrace_on _tdu._tds._td_dtrace_on +#define td_dtrace_step _tdu._tds._td_dtrace_step +#define td_dtrace_ret _tdu._tds._td_dtrace_ret +#define td_dtrace_ast _tdu._tds._td_dtrace_ast +#define td_dtrace_reg _tdu._tds._td_dtrace_reg +#define td_dtrace_wouldrecurse _tdu._tds._td_dtrace_wouldrecurse uintptr_t td_dtrace_pc; /* DTrace saved pc from fasttrap. */ uintptr_t td_dtrace_npc; /* DTrace next pc from fasttrap. */ @@ -111,6 +114,7 @@ #define t_dtrace_regv td_dtrace->td_dtrace_regv #define t_dtrace_sscr td_dtrace->td_dtrace_sscr #define t_dtrace_systrace_args td_dtrace->td_systrace_args +#define t_dtrace_wouldrecurse td_dtrace->td_dtrace_wouldrecurse #define p_dtrace_helpers p_dtrace->p_dtrace_helpers #define p_dtrace_count p_dtrace->p_dtrace_count #define p_dtrace_probes p_dtrace->p_dtrace_probes