1179237Sjb/*-
2179237Sjb * Copyright (C) 2008 John Birrell <jb@freebsd.org>.
3179237Sjb * All rights reserved.
4179237Sjb *
5179237Sjb * Redistribution and use in source and binary forms, with or without
6179237Sjb * modification, are permitted provided that the following conditions
7179237Sjb * are met:
8179237Sjb * 1. Redistributions of source code must retain the above copyright
9179237Sjb *    notice(s), this list of conditions and the following disclaimer as
10179237Sjb *    the first lines of this file unmodified other than the possible
11179237Sjb *    addition of one or more copyright notices.
12179237Sjb * 2. Redistributions in binary form must reproduce the above copyright
13179237Sjb *    notice(s), this list of conditions and the following disclaimer in the
14179237Sjb *    documentation and/or other materials provided with the distribution.
15179237Sjb *
16179237Sjb * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
17179237Sjb * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18179237Sjb * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19179237Sjb * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
20179237Sjb * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21179237Sjb * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22179237Sjb * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23179237Sjb * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24179237Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25179237Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26179237Sjb * DAMAGE.
27179237Sjb *
28179237Sjb * $FreeBSD$
29179237Sjb *
30179237Sjb */
31179237Sjb
32179237Sjb#ifdef DEBUG
33179237Sjb
34226452Smarcel#include <machine/atomic.h>
35179237Sjb
36179237Sjb#define DTRACE_DEBUG_BUFR_SIZE	(32 * 1024)
37179237Sjb
38179237Sjbstruct dtrace_debug_data {
39244631Srstone	uintptr_t lock __aligned(CACHE_LINE_SIZE);
40179237Sjb	char bufr[DTRACE_DEBUG_BUFR_SIZE];
41179237Sjb	char *first;
42179237Sjb	char *last;
43179237Sjb	char *next;
44179237Sjb} dtrace_debug_data[MAXCPU];
45179237Sjb
46179237Sjbstatic char dtrace_debug_bufr[DTRACE_DEBUG_BUFR_SIZE];
47179237Sjb
48179237Sjbstatic void
49179237Sjbdtrace_debug_lock(int cpu)
50179237Sjb{
51244631Srstone	 uintptr_t tid;
52244631Srstone
53244631Srstone	tid = (uintptr_t)curthread;
54244631Srstone	spinlock_enter();
55244631Srstone	while (atomic_cmpset_acq_ptr(&dtrace_debug_data[cpu].lock, 0, tid) == 0)		/* Loop until the lock is obtained. */
56179237Sjb		;
57179237Sjb}
58179237Sjb
59179237Sjbstatic void
60179237Sjbdtrace_debug_unlock(int cpu)
61179237Sjb{
62244631Srstone	atomic_store_rel_ptr(&dtrace_debug_data[cpu].lock, 0);
63244631Srstone	spinlock_exit();
64179237Sjb}
65179237Sjb
66179237Sjbstatic void
67179237Sjbdtrace_debug_init(void *dummy)
68179237Sjb{
69179237Sjb	int i;
70179237Sjb	struct dtrace_debug_data *d;
71179237Sjb
72209059Sjhb	CPU_FOREACH(i) {
73179237Sjb		d = &dtrace_debug_data[i];
74179237Sjb
75179237Sjb		if (d->first == NULL) {
76179237Sjb			d->first = d->bufr;
77179237Sjb			d->next = d->bufr;
78179237Sjb			d->last = d->bufr + DTRACE_DEBUG_BUFR_SIZE - 1;
79179237Sjb			*(d->last) = '\0';
80179237Sjb		}
81179237Sjb	}
82179237Sjb}
83179237Sjb
84179237SjbSYSINIT(dtrace_debug_init, SI_SUB_KDTRACE, SI_ORDER_ANY, dtrace_debug_init, NULL);
85179237SjbSYSINIT(dtrace_debug_smpinit, SI_SUB_SMP, SI_ORDER_ANY, dtrace_debug_init, NULL);
86179237Sjb
87179237Sjbstatic void
88179237Sjbdtrace_debug_output(void)
89179237Sjb{
90179237Sjb	char *p;
91179237Sjb	int i;
92179237Sjb	struct dtrace_debug_data *d;
93179237Sjb	uintptr_t count;
94179237Sjb
95209059Sjhb	CPU_FOREACH(i) {
96179237Sjb		dtrace_debug_lock(i);
97179237Sjb
98179237Sjb		d = &dtrace_debug_data[i];
99179237Sjb
100179237Sjb		count = 0;
101179237Sjb
102179237Sjb		if (d->first < d->next) {
103179237Sjb			char *p1 = dtrace_debug_bufr;
104179237Sjb
105179237Sjb			count = (uintptr_t) d->next - (uintptr_t) d->first;
106179237Sjb
107179237Sjb			for (p = d->first; p < d->next; p++)
108179237Sjb				*p1++ = *p;
109179237Sjb		} else if (d->next > d->first) {
110179237Sjb			char *p1 = dtrace_debug_bufr;
111179237Sjb
112179237Sjb			count = (uintptr_t) d->last - (uintptr_t) d->first;
113179237Sjb
114179237Sjb			for (p = d->first; p < d->last; p++)
115179237Sjb				*p1++ = *p;
116179237Sjb
117179237Sjb			count += (uintptr_t) d->next - (uintptr_t) d->bufr;
118179237Sjb
119179237Sjb			for (p = d->bufr; p < d->next; p++)
120179237Sjb				*p1++ = *p;
121179237Sjb		}
122179237Sjb
123179237Sjb		d->first = d->bufr;
124179237Sjb		d->next = d->bufr;
125179237Sjb
126179237Sjb		dtrace_debug_unlock(i);
127179237Sjb
128179237Sjb		if (count > 0) {
129179237Sjb			char *last = dtrace_debug_bufr + count;
130179237Sjb
131179237Sjb			p = dtrace_debug_bufr;
132179237Sjb
133179237Sjb			while (p < last) {
134179237Sjb				if (*p == '\0') {
135179237Sjb					p++;
136179237Sjb					continue;
137179237Sjb				}
138179237Sjb
139179237Sjb				printf("%s", p);
140179237Sjb
141179237Sjb				p += strlen(p);
142179237Sjb			}
143179237Sjb		}
144179237Sjb	}
145179237Sjb}
146179237Sjb
147179237Sjb/*
148179237Sjb * Functions below here are called from the probe context, so they can't call
149179237Sjb * _any_ functions outside the dtrace module without running foul of the function
150179237Sjb * boundary trace provider (fbt). The purpose of these functions is limited to
151179237Sjb * buffering debug strings for output when the probe completes on the current CPU.
152179237Sjb */
153179237Sjb
154179237Sjbstatic __inline void
155244631Srstonedtrace_debug__putc(int cpu, char c)
156179237Sjb{
157244631Srstone	struct dtrace_debug_data *d;
158179237Sjb
159244631Srstone	d = &dtrace_debug_data[cpu];
160179237Sjb	*d->next++ = c;
161179237Sjb
162179237Sjb	if (d->next == d->last)
163179237Sjb		d->next = d->bufr;
164179237Sjb
165179237Sjb	*(d->next) = '\0';
166179237Sjb
167179237Sjb	if (d->next == d->first)
168179237Sjb		d->first++;
169179237Sjb
170179237Sjb	if (d->first == d->last)
171179237Sjb		d->first = d->bufr;
172179237Sjb}
173179237Sjb
174179237Sjbstatic void __used
175179237Sjbdtrace_debug_putc(char c)
176179237Sjb{
177244631Srstone	int cpu;
178179237Sjb
179244631Srstone	cpu = curcpu;
180244631Srstone	dtrace_debug_lock(cpu);
181179237Sjb
182244631Srstone	dtrace_debug__putc(cpu, c);
183244631Srstone
184244631Srstone	dtrace_debug_unlock(cpu);
185179237Sjb}
186179237Sjb
187179237Sjbstatic void __used
188179237Sjbdtrace_debug_puts(const char *s)
189179237Sjb{
190244631Srstone	int cpu;
191244631Srstone
192244631Srstone	cpu = curcpu;
193244631Srstone	dtrace_debug_lock(cpu);
194179237Sjb
195179237Sjb	while (*s != '\0')
196244631Srstone		dtrace_debug__putc(cpu, *s++);
197179237Sjb
198244631Srstone	dtrace_debug__putc(cpu, '\0');
199179237Sjb
200244631Srstone	dtrace_debug_unlock(cpu);
201179237Sjb}
202179237Sjb
203179237Sjb/*
204179237Sjb * Snaffled from sys/kern/subr_prf.c
205179237Sjb *
206179237Sjb * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
207179237Sjb * order; return an optional length and a pointer to the last character
208179237Sjb * written in the buffer (i.e., the first character of the string).
209179237Sjb * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
210179237Sjb */
211179237Sjbstatic char *
212179237Sjbdtrace_debug_ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
213179237Sjb{
214179237Sjb	char *p, c;
215179237Sjb
216179237Sjb	p = nbuf;
217179237Sjb	*p = '\0';
218179237Sjb	do {
219179237Sjb		c = hex2ascii(num % base);
220179237Sjb		*++p = upper ? toupper(c) : c;
221179237Sjb	} while (num /= base);
222179237Sjb	if (lenp)
223179237Sjb		*lenp = p - nbuf;
224179237Sjb	return (p);
225179237Sjb}
226179237Sjb
227179237Sjb#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
228179237Sjb
229179237Sjbstatic void
230244631Srstonedtrace_debug_vprintf(int cpu, const char *fmt, va_list ap)
231179237Sjb{
232179237Sjb	char nbuf[MAXNBUF];
233179237Sjb	const char *p, *percent, *q;
234179237Sjb	u_char *up;
235179237Sjb	int ch, n;
236179237Sjb	uintmax_t num;
237179237Sjb	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
238179237Sjb	int cflag, hflag, jflag, tflag, zflag;
239179237Sjb	int dwidth, upper;
240179237Sjb	int radix = 10;
241179237Sjb	char padc;
242179237Sjb	int stop = 0, retval = 0;
243179237Sjb
244179237Sjb	num = 0;
245179237Sjb
246179237Sjb	if (fmt == NULL)
247179237Sjb		fmt = "(fmt null)\n";
248179237Sjb
249179237Sjb	for (;;) {
250179237Sjb		padc = ' ';
251179237Sjb		width = 0;
252179237Sjb		while ((ch = (u_char)*fmt++) != '%' || stop) {
253179237Sjb			if (ch == '\0') {
254244631Srstone				dtrace_debug__putc(cpu, '\0');
255179237Sjb				return;
256179237Sjb			}
257244631Srstone			dtrace_debug__putc(cpu, ch);
258179237Sjb		}
259179237Sjb		percent = fmt - 1;
260179237Sjb		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
261179237Sjb		sign = 0; dot = 0; dwidth = 0; upper = 0;
262179237Sjb		cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
263179237Sjbreswitch:	switch (ch = (u_char)*fmt++) {
264179237Sjb		case '.':
265179237Sjb			dot = 1;
266179237Sjb			goto reswitch;
267179237Sjb		case '#':
268179237Sjb			sharpflag = 1;
269179237Sjb			goto reswitch;
270179237Sjb		case '+':
271179237Sjb			sign = 1;
272179237Sjb			goto reswitch;
273179237Sjb		case '-':
274179237Sjb			ladjust = 1;
275179237Sjb			goto reswitch;
276179237Sjb		case '%':
277244631Srstone			dtrace_debug__putc(cpu, ch);
278179237Sjb			break;
279179237Sjb		case '*':
280179237Sjb			if (!dot) {
281179237Sjb				width = va_arg(ap, int);
282179237Sjb				if (width < 0) {
283179237Sjb					ladjust = !ladjust;
284179237Sjb					width = -width;
285179237Sjb				}
286179237Sjb			} else {
287179237Sjb				dwidth = va_arg(ap, int);
288179237Sjb			}
289179237Sjb			goto reswitch;
290179237Sjb		case '0':
291179237Sjb			if (!dot) {
292179237Sjb				padc = '0';
293179237Sjb				goto reswitch;
294179237Sjb			}
295179237Sjb		case '1': case '2': case '3': case '4':
296179237Sjb		case '5': case '6': case '7': case '8': case '9':
297179237Sjb				for (n = 0;; ++fmt) {
298179237Sjb					n = n * 10 + ch - '0';
299179237Sjb					ch = *fmt;
300179237Sjb					if (ch < '0' || ch > '9')
301179237Sjb						break;
302179237Sjb				}
303179237Sjb			if (dot)
304179237Sjb				dwidth = n;
305179237Sjb			else
306179237Sjb				width = n;
307179237Sjb			goto reswitch;
308179237Sjb		case 'b':
309179237Sjb			num = (u_int)va_arg(ap, int);
310179237Sjb			p = va_arg(ap, char *);
311179237Sjb			for (q = dtrace_debug_ksprintn(nbuf, num, *p++, NULL, 0); *q;)
312244631Srstone				dtrace_debug__putc(cpu, *q--);
313179237Sjb
314179237Sjb			if (num == 0)
315179237Sjb				break;
316179237Sjb
317179237Sjb			for (tmp = 0; *p;) {
318179237Sjb				n = *p++;
319179237Sjb				if (num & (1 << (n - 1))) {
320244631Srstone					dtrace_debug__putc(cpu, tmp ? ',' : '<');
321179237Sjb					for (; (n = *p) > ' '; ++p)
322244631Srstone						dtrace_debug__putc(cpu, n);
323179237Sjb					tmp = 1;
324179237Sjb				} else
325179237Sjb					for (; *p > ' '; ++p)
326179237Sjb						continue;
327179237Sjb			}
328179237Sjb			if (tmp)
329244631Srstone				dtrace_debug__putc(cpu, '>');
330179237Sjb			break;
331179237Sjb		case 'c':
332244631Srstone			dtrace_debug__putc(cpu, va_arg(ap, int));
333179237Sjb			break;
334179237Sjb		case 'D':
335179237Sjb			up = va_arg(ap, u_char *);
336179237Sjb			p = va_arg(ap, char *);
337179237Sjb			if (!width)
338179237Sjb				width = 16;
339179237Sjb			while(width--) {
340244631Srstone				dtrace_debug__putc(cpu, hex2ascii(*up >> 4));
341244631Srstone				dtrace_debug__putc(cpu, hex2ascii(*up & 0x0f));
342179237Sjb				up++;
343179237Sjb				if (width)
344179237Sjb					for (q=p;*q;q++)
345244631Srstone						dtrace_debug__putc(cpu, *q);
346179237Sjb			}
347179237Sjb			break;
348179237Sjb		case 'd':
349179237Sjb		case 'i':
350179237Sjb			base = 10;
351179237Sjb			sign = 1;
352179237Sjb			goto handle_sign;
353179237Sjb		case 'h':
354179237Sjb			if (hflag) {
355179237Sjb				hflag = 0;
356179237Sjb				cflag = 1;
357179237Sjb			} else
358179237Sjb				hflag = 1;
359179237Sjb			goto reswitch;
360179237Sjb		case 'j':
361179237Sjb			jflag = 1;
362179237Sjb			goto reswitch;
363179237Sjb		case 'l':
364179237Sjb			if (lflag) {
365179237Sjb				lflag = 0;
366179237Sjb				qflag = 1;
367179237Sjb			} else
368179237Sjb				lflag = 1;
369179237Sjb			goto reswitch;
370179237Sjb		case 'n':
371179237Sjb			if (jflag)
372179237Sjb				*(va_arg(ap, intmax_t *)) = retval;
373179237Sjb			else if (qflag)
374179237Sjb				*(va_arg(ap, quad_t *)) = retval;
375179237Sjb			else if (lflag)
376179237Sjb				*(va_arg(ap, long *)) = retval;
377179237Sjb			else if (zflag)
378179237Sjb				*(va_arg(ap, size_t *)) = retval;
379179237Sjb			else if (hflag)
380179237Sjb				*(va_arg(ap, short *)) = retval;
381179237Sjb			else if (cflag)
382179237Sjb				*(va_arg(ap, char *)) = retval;
383179237Sjb			else
384179237Sjb				*(va_arg(ap, int *)) = retval;
385179237Sjb			break;
386179237Sjb		case 'o':
387179237Sjb			base = 8;
388179237Sjb			goto handle_nosign;
389179237Sjb		case 'p':
390179237Sjb			base = 16;
391179237Sjb			sharpflag = (width == 0);
392179237Sjb			sign = 0;
393179237Sjb			num = (uintptr_t)va_arg(ap, void *);
394179237Sjb			goto number;
395179237Sjb		case 'q':
396179237Sjb			qflag = 1;
397179237Sjb			goto reswitch;
398179237Sjb		case 'r':
399179237Sjb			base = radix;
400179237Sjb			if (sign)
401179237Sjb				goto handle_sign;
402179237Sjb			goto handle_nosign;
403179237Sjb		case 's':
404179237Sjb			p = va_arg(ap, char *);
405179237Sjb			if (p == NULL)
406179237Sjb				p = "(null)";
407179237Sjb			if (!dot)
408179237Sjb				n = strlen (p);
409179237Sjb			else
410179237Sjb				for (n = 0; n < dwidth && p[n]; n++)
411179237Sjb					continue;
412179237Sjb
413179237Sjb			width -= n;
414179237Sjb
415179237Sjb			if (!ladjust && width > 0)
416179237Sjb				while (width--)
417244631Srstone					dtrace_debug__putc(cpu, padc);
418179237Sjb			while (n--)
419244631Srstone				dtrace_debug__putc(cpu, *p++);
420179237Sjb			if (ladjust && width > 0)
421179237Sjb				while (width--)
422244631Srstone					dtrace_debug__putc(cpu, padc);
423179237Sjb			break;
424179237Sjb		case 't':
425179237Sjb			tflag = 1;
426179237Sjb			goto reswitch;
427179237Sjb		case 'u':
428179237Sjb			base = 10;
429179237Sjb			goto handle_nosign;
430179237Sjb		case 'X':
431179237Sjb			upper = 1;
432179237Sjb		case 'x':
433179237Sjb			base = 16;
434179237Sjb			goto handle_nosign;
435179237Sjb		case 'y':
436179237Sjb			base = 16;
437179237Sjb			sign = 1;
438179237Sjb			goto handle_sign;
439179237Sjb		case 'z':
440179237Sjb			zflag = 1;
441179237Sjb			goto reswitch;
442179237Sjbhandle_nosign:
443179237Sjb			sign = 0;
444179237Sjb			if (jflag)
445179237Sjb				num = va_arg(ap, uintmax_t);
446179237Sjb			else if (qflag)
447179237Sjb				num = va_arg(ap, u_quad_t);
448179237Sjb			else if (tflag)
449179237Sjb				num = va_arg(ap, ptrdiff_t);
450179237Sjb			else if (lflag)
451179237Sjb				num = va_arg(ap, u_long);
452179237Sjb			else if (zflag)
453179237Sjb				num = va_arg(ap, size_t);
454179237Sjb			else if (hflag)
455179237Sjb				num = (u_short)va_arg(ap, int);
456179237Sjb			else if (cflag)
457179237Sjb				num = (u_char)va_arg(ap, int);
458179237Sjb			else
459179237Sjb				num = va_arg(ap, u_int);
460179237Sjb			goto number;
461179237Sjbhandle_sign:
462179237Sjb			if (jflag)
463179237Sjb				num = va_arg(ap, intmax_t);
464179237Sjb			else if (qflag)
465179237Sjb				num = va_arg(ap, quad_t);
466179237Sjb			else if (tflag)
467179237Sjb				num = va_arg(ap, ptrdiff_t);
468179237Sjb			else if (lflag)
469179237Sjb				num = va_arg(ap, long);
470179237Sjb			else if (zflag)
471179237Sjb				num = va_arg(ap, size_t);
472179237Sjb			else if (hflag)
473179237Sjb				num = (short)va_arg(ap, int);
474179237Sjb			else if (cflag)
475179237Sjb				num = (char)va_arg(ap, int);
476179237Sjb			else
477179237Sjb				num = va_arg(ap, int);
478179237Sjbnumber:
479179237Sjb			if (sign && (intmax_t)num < 0) {
480179237Sjb				neg = 1;
481179237Sjb				num = -(intmax_t)num;
482179237Sjb			}
483179237Sjb			p = dtrace_debug_ksprintn(nbuf, num, base, &tmp, upper);
484179237Sjb			if (sharpflag && num != 0) {
485179237Sjb				if (base == 8)
486179237Sjb					tmp++;
487179237Sjb				else if (base == 16)
488179237Sjb					tmp += 2;
489179237Sjb			}
490179237Sjb			if (neg)
491179237Sjb				tmp++;
492179237Sjb
493179237Sjb			if (!ladjust && padc != '0' && width
494179237Sjb			    && (width -= tmp) > 0)
495179237Sjb				while (width--)
496244631Srstone					dtrace_debug__putc(cpu, padc);
497179237Sjb			if (neg)
498244631Srstone				dtrace_debug__putc(cpu, '-');
499179237Sjb			if (sharpflag && num != 0) {
500179237Sjb				if (base == 8) {
501244631Srstone					dtrace_debug__putc(cpu, '0');
502179237Sjb				} else if (base == 16) {
503244631Srstone					dtrace_debug__putc(cpu, '0');
504244631Srstone					dtrace_debug__putc(cpu, 'x');
505179237Sjb				}
506179237Sjb			}
507179237Sjb			if (!ladjust && width && (width -= tmp) > 0)
508179237Sjb				while (width--)
509244631Srstone					dtrace_debug__putc(cpu, padc);
510179237Sjb
511179237Sjb			while (*p)
512244631Srstone				dtrace_debug__putc(cpu, *p--);
513179237Sjb
514179237Sjb			if (ladjust && width && (width -= tmp) > 0)
515179237Sjb				while (width--)
516244631Srstone					dtrace_debug__putc(cpu, padc);
517179237Sjb
518179237Sjb			break;
519179237Sjb		default:
520179237Sjb			while (percent < fmt)
521244631Srstone				dtrace_debug__putc(cpu, *percent++);
522179237Sjb			/*
523179237Sjb			 * Since we ignore an formatting argument it is no
524179237Sjb			 * longer safe to obey the remaining formatting
525179237Sjb			 * arguments as the arguments will no longer match
526179237Sjb			 * the format specs.
527179237Sjb			 */
528179237Sjb			stop = 1;
529179237Sjb			break;
530179237Sjb		}
531179237Sjb	}
532179237Sjb
533244631Srstone	dtrace_debug__putc(cpu, '\0');
534179237Sjb}
535179237Sjb
536179237Sjbvoid
537179237Sjbdtrace_debug_printf(const char *fmt, ...)
538179237Sjb{
539179237Sjb	va_list ap;
540244631Srstone	int cpu;
541179237Sjb
542244631Srstone	cpu = curcpu;
543244631Srstone	dtrace_debug_lock(cpu);
544179237Sjb
545179237Sjb	va_start(ap, fmt);
546179237Sjb
547244631Srstone	dtrace_debug_vprintf(cpu, fmt, ap);
548179237Sjb
549179237Sjb	va_end(ap);
550179237Sjb
551244631Srstone	dtrace_debug_unlock(cpu);
552179237Sjb}
553179237Sjb
554179237Sjb#else
555179237Sjb
556179237Sjb#define dtrace_debug_output()
557179237Sjb#define dtrace_debug_puts(_s)
558179237Sjb#define dtrace_debug_printf(fmt, ...)
559179237Sjb
560179237Sjb#endif
561