1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
<table class="head">
<tr>
<td class="head-ltitle">KASSERT(9)</td>
<td class="head-vol">Kernel Developer's Manual</td>
<td class="head-rtitle">KASSERT(9)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">KASSERT</code> — <span class="Nd">kernel
expression verification macros</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="Cd">options INVARIANTS</code></p>
<p class="Pp">
<br/>
<code class="In">#include <<a class="In">sys/param.h</a>></code>
<br/>
<code class="In">#include <<a class="In">sys/systm.h</a>></code></p>
<p class="Pp"><code class="Fn">KASSERT</code>(<var class="Fa" style="white-space: nowrap;">expression</var>,
<var class="Fa" style="white-space: nowrap;">msg</var>);</p>
<p class="Pp"><code class="Fn">MPASS</code>(<var class="Fa" style="white-space: nowrap;">expression</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">Assertions are widely used within the
<span class="Ux">FreeBSD</span> kernel to verify programmatic assumptions.
For violations of run-time assumptions and invariants, it is desirable to
fail as soon and as loudly as possible. Assertions are optional code; for
non-recoverable error conditions an explicit call to
<a class="Xr">panic(9)</a> is usually preferred.</p>
<p class="Pp" id="KASSERT">The
<a class="permalink" href="#KASSERT"><code class="Fn">KASSERT</code></a>()
macro tests the given boolean <var class="Fa">expression</var>. If
<var class="Fa">expression</var> evaluates to <code class="Dv">false</code>,
and the kernel is compiled with <code class="Cd">options INVARIANTS</code>,
the <a class="Xr">panic(9)</a> function is called. This terminates the
running system at the point of the error, possibly dropping into the kernel
debugger or initiating a kernel core dump. The second argument,
<var class="Fa">msg</var>, is a <a class="Xr">printf(9)</a> format string
and its arguments, enclosed in parentheses. The formatted string will become
the panic string.</p>
<p class="Pp">In a kernel that is built without <code class="Cd">options
INVARIANTS</code>, the assertion macros are defined to be no-ops. This
eliminates the runtime overhead of widespread assertions from release builds
of the kernel. Therefore, checks which can be performed in a constant amount
of time can be added as assertions without concern about their performance
impact. More expensive checks, such as those that output to console, or
verify the integrity of a chain of objects are generally best hidden behind
the <code class="Cd">DIAGNOSTIC</code> kernel option.</p>
<p class="Pp" id="MPASS">The
<a class="permalink" href="#MPASS"><code class="Fn">MPASS</code></a>() macro
(read as: "must-pass") is a convenience wrapper around
<code class="Fn">KASSERT</code>() that automatically generates a simple
assertion message including file and line information.</p>
<section class="Ss">
<h2 class="Ss" id="Assertion_Guidelines"><a class="permalink" href="#Assertion_Guidelines">Assertion
Guidelines</a></h2>
<p class="Pp">When adding new assertions, keep in mind their primary purpose: to
aid in identifying and debugging of complex error conditions.</p>
<p class="Pp">The panic messages resulting from assertion failures should be
useful without the resulting kernel dump; the message may be included in a
bug report, and should contain the relevant information needed to discern
how the assertion was violated. This is especially important when the error
condition is difficult or impossible for the developer to reproduce
locally.</p>
<p class="Pp">Therefore, assertions should adhere to the following
guidelines:</p>
<ol class="Bl-enum">
<li>Whenever possible, the value of a runtime variable checked by an assertion
condition should appear in its message.</li>
<li>Unrelated conditions must appear in separate assertions.</li>
<li>Multiple related conditions should be distinguishable (e.g. by value), or
split into separate assertions.</li>
<li>When in doubt, print more information, not less.</li>
</ol>
<p class="Pp">Combined, this gives greater clarity into the exact cause of an
assertion panic; see <a class="Sx" href="#EXAMPLES">EXAMPLES</a> below.</p>
</section>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<p class="Pp">A hypothetical <var class="Vt">struct foo</var> object must not
have its 'active' flag set when calling
<code class="Fn">foo_dealloc</code>():</p>
<div class="Bd Pp Bd-indent Li">
<pre>void
foo_dealloc(struct foo *fp)
{
KASSERT((fp->foo_flags & FOO_ACTIVE) == 0,
("%s: fp %p is still active, flags=%x", __func__, fp,
fp->foo_flags));
...
}</pre>
</div>
<p class="Pp">This assertion provides the full flag set for the object, as well
as the memory pointer, which may be used by a debugger to examine the object
in detail (for example with a 'show foo' command in
<a class="Xr">ddb(4)</a>).</p>
<p class="Pp">The assertion</p>
<div class="Bd Pp Bd-indent Li">
<pre>MPASS(td == curthread);</pre>
</div>
<p class="Pp">located on line 87 of a file named foo.c would generate the
following panic message:</p>
<div class="Bd Pp Bd-indent Li">
<pre>panic: Assertion td == curthread failed at foo.c:87</pre>
</div>
<p class="Pp">This is a simple condition, and the message provides enough
information to investigate the failure.</p>
<p class="Pp">The assertion</p>
<div class="Bd Pp Bd-indent Li">
<pre>MPASS(td == curthread && (sz >= SIZE_MIN && sz <= SIZE_MAX));</pre>
</div>
<p class="Pp" id="NOT">is
<a class="permalink" href="#NOT"><i class="Em">NOT</i></a> useful enough.
The message doesn't indicate which part of the assertion was violated, nor
does it report the value of <code class="Dv">sz</code>, which may be
critical to understanding
<a class="permalink" href="#why"><i class="Em" id="why">why</i></a> the
assertion failed.</p>
<p class="Pp">According to the guidelines above, this would be correctly
expressed as:</p>
<div class="Bd Pp Bd-indent Li">
<pre>MPASS(td == curthread);
KASSERT(sz >= SIZE_MIN && sz <= SIZE_MAX,
("invalid size argument: %u", sz));</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">The <code class="Nm">MPASS</code> macro first appeared in
<span class="Ux">BSD/OS</span> and was imported into
<span class="Ux">FreeBSD 5.0</span>. The name originates as an acronym of
"multi-processor assert", but has evolved to mean "must
pass", or "must-pass assert".</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<p class="Pp"><a class="Xr">panic(9)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp">This manual page was written by <span class="An">Jonathan M.
Bresler</span>
<<a class="Mt" href="mailto:jmb@FreeBSD.org">jmb@FreeBSD.org</a>> and
<br/>
<span class="An">Mitchell Horne</span>
<<a class="Mt" href="mailto:mhorne@FreeBSD.org">mhorne@FreeBSD.org</a>>.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">March 19, 2024</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|