1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5209962Smm * Common Development and Distribution License (the "License").
6209962Smm * You may not use this file except in compliance with the License.
7168404Spjd *
8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9168404Spjd * or http://www.opensolaris.org/os/licensing.
10168404Spjd * See the License for the specific language governing permissions
11168404Spjd * and limitations under the License.
12168404Spjd *
13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15168404Spjd * If applicable, add the following below this CDDL HEADER, with the
16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
18168404Spjd *
19168404Spjd * CDDL HEADER END
20168404Spjd */
21168404Spjd/*
22219089Spjd * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23168404Spjd * Use is subject to license terms.
24168404Spjd */
25168404Spjd
26243674Smm/*
27243674Smm * Copyright (c) 2012 by Delphix. All rights reserved.
28243674Smm */
29243674Smm
30168404Spjd/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
31168404Spjd/*	  All Rights Reserved	*/
32168404Spjd
33168404Spjd#ifndef _SYS_DEBUG_H
34168404Spjd#define	_SYS_DEBUG_H
35168404Spjd
36168404Spjd#include <sys/types.h>
37219089Spjd#include <sys/note.h>
38168404Spjd
39168404Spjd#ifdef	__cplusplus
40168404Spjdextern "C" {
41168404Spjd#endif
42168404Spjd
43168404Spjd/*
44168404Spjd * ASSERT(ex) causes a panic or debugger entry if expression ex is not
45168404Spjd * true.  ASSERT() is included only for debugging, and is a no-op in
46168404Spjd * production kernels.  VERIFY(ex), on the other hand, behaves like
47168404Spjd * ASSERT and is evaluated on both debug and non-debug kernels.
48168404Spjd */
49168404Spjd
50168404Spjd#if defined(__STDC__)
51168404Spjdextern int assfail(const char *, const char *, int);
52168404Spjd#define	VERIFY(EX) ((void)((EX) || assfail(#EX, __FILE__, __LINE__)))
53179198Sjb#ifdef DEBUG
54209962Smm#define	ASSERT(EX) ((void)((EX) || assfail(#EX, __FILE__, __LINE__)))
55168404Spjd#else
56168404Spjd#define	ASSERT(x)  ((void)0)
57168404Spjd#endif
58168404Spjd#else	/* defined(__STDC__) */
59168404Spjdextern int assfail();
60168404Spjd#define	VERIFY(EX) ((void)((EX) || assfail("EX", __FILE__, __LINE__)))
61179198Sjb#ifdef DEBUG
62209962Smm#define	ASSERT(EX) ((void)((EX) || assfail("EX", __FILE__, __LINE__)))
63168404Spjd#else
64168404Spjd#define	ASSERT(x)  ((void)0)
65168404Spjd#endif
66168404Spjd#endif	/* defined(__STDC__) */
67168404Spjd
68168404Spjd/*
69168404Spjd * Assertion variants sensitive to the compilation data model
70168404Spjd */
71168404Spjd#if defined(_LP64)
72168404Spjd#define	ASSERT64(x)	ASSERT(x)
73168404Spjd#define	ASSERT32(x)
74168404Spjd#else
75168404Spjd#define	ASSERT64(x)
76168404Spjd#define	ASSERT32(x)	ASSERT(x)
77168404Spjd#endif
78168404Spjd
79168404Spjd/*
80219089Spjd * IMPLY and EQUIV are assertions of the form:
81219089Spjd *
82219089Spjd *	if (a) then (b)
83219089Spjd * and
84219089Spjd *	if (a) then (b) *AND* if (b) then (a)
85219089Spjd */
86219089Spjd#ifdef DEBUG
87219089Spjd#define	IMPLY(A, B) \
88219089Spjd	((void)(((!(A)) || (B)) || \
89219089Spjd	    assfail("(" #A ") implies (" #B ")", __FILE__, __LINE__)))
90219089Spjd#define	EQUIV(A, B) \
91219089Spjd	((void)((!!(A) == !!(B)) || \
92219089Spjd	    assfail("(" #A ") is equivalent to (" #B ")", __FILE__, __LINE__)))
93219089Spjd#else
94219089Spjd#define	IMPLY(A, B) ((void)0)
95219089Spjd#define	EQUIV(A, B) ((void)0)
96219089Spjd#endif
97219089Spjd
98219089Spjd/*
99168404Spjd * ASSERT3() behaves like ASSERT() except that it is an explicit conditional,
100168404Spjd * and prints out the values of the left and right hand expressions as part of
101168404Spjd * the panic message to ease debugging.  The three variants imply the type
102168404Spjd * of their arguments.  ASSERT3S() is for signed data types, ASSERT3U() is
103168404Spjd * for unsigned, and ASSERT3P() is for pointers.  The VERIFY3*() macros
104168404Spjd * have the same relationship as above.
105168404Spjd */
106168404Spjdextern void assfail3(const char *, uintmax_t, const char *, uintmax_t,
107168404Spjd    const char *, int);
108168404Spjd#define	VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) do { \
109168404Spjd	const TYPE __left = (TYPE)(LEFT); \
110168404Spjd	const TYPE __right = (TYPE)(RIGHT); \
111168404Spjd	if (!(__left OP __right)) \
112168404Spjd		assfail3(#LEFT " " #OP " " #RIGHT, \
113168404Spjd			(uintmax_t)__left, #OP, (uintmax_t)__right, \
114168404Spjd			__FILE__, __LINE__); \
115168404Spjd_NOTE(CONSTCOND) } while (0)
116168404Spjd
117168404Spjd#define	VERIFY3S(x, y, z)	VERIFY3_IMPL(x, y, z, int64_t)
118168404Spjd#define	VERIFY3U(x, y, z)	VERIFY3_IMPL(x, y, z, uint64_t)
119168404Spjd#define	VERIFY3P(x, y, z)	VERIFY3_IMPL(x, y, z, uintptr_t)
120243674Smm#define	VERIFY0(x)		VERIFY3_IMPL(x, ==, 0, uintmax_t)
121243674Smm
122179198Sjb#ifdef DEBUG
123209962Smm#define	ASSERT3S(x, y, z)	VERIFY3_IMPL(x, y, z, int64_t)
124209962Smm#define	ASSERT3U(x, y, z)	VERIFY3_IMPL(x, y, z, uint64_t)
125209962Smm#define	ASSERT3P(x, y, z)	VERIFY3_IMPL(x, y, z, uintptr_t)
126243674Smm#define	ASSERT0(x)		VERIFY3_IMPL(x, ==, 0, uintmax_t)
127168404Spjd#else
128168404Spjd#define	ASSERT3S(x, y, z)	((void)0)
129168404Spjd#define	ASSERT3U(x, y, z)	((void)0)
130168404Spjd#define	ASSERT3P(x, y, z)	((void)0)
131243674Smm#define	ASSERT0(x)		((void)0)
132168404Spjd#endif
133168404Spjd
134168404Spjd#ifdef	_KERNEL
135168404Spjd
136168404Spjdextern void abort_sequence_enter(char *);
137168404Spjdextern void debug_enter(char *);
138168404Spjd
139168404Spjd#endif	/* _KERNEL */
140168404Spjd
141168404Spjd#if defined(DEBUG) && !defined(__sun)
142168404Spjd/* CSTYLED */
143168404Spjd#define	STATIC
144168404Spjd#else
145168404Spjd/* CSTYLED */
146168404Spjd#define	STATIC static
147168404Spjd#endif
148168404Spjd
149168404Spjd#ifdef	__cplusplus
150168404Spjd}
151168404Spjd#endif
152168404Spjd
153168404Spjd#endif	/* _SYS_DEBUG_H */
154