summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/KASSERT.9 3.html
blob: 8b96b200cb8c1ece7ab7c541dec81999ff72b459 (plain)
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> &#x2014; <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 &lt;<a class="In">sys/param.h</a>&gt;</code>
  <br/>
  <code class="In">#include &lt;<a class="In">sys/systm.h</a>&gt;</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: &quot;must-pass&quot;) 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-&gt;foo_flags &amp; FOO_ACTIVE) == 0,
	    (&quot;%s: fp %p is still active, flags=%x&quot;, __func__, fp,
	    fp-&gt;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 &amp;&amp; (sz &gt;= SIZE_MIN &amp;&amp; sz &lt;= 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 &gt;= SIZE_MIN &amp;&amp; sz &lt;= SIZE_MAX,
    (&quot;invalid size argument: %u&quot;, 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
    &quot;multi-processor assert&quot;, but has evolved to mean &quot;must
    pass&quot;, or &quot;must-pass assert&quot;.</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>
    &lt;<a class="Mt" href="mailto:jmb@FreeBSD.org">jmb@FreeBSD.org</a>&gt; and
  <br/>
  <span class="An">Mitchell Horne</span>
    &lt;<a class="Mt" href="mailto:mhorne@FreeBSD.org">mhorne@FreeBSD.org</a>&gt;.</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>