1.\" SPDX-License-Identifier: BSD-2-Clause 2.\" 3.\" Copyright (c) 2000 Jonathan M. Bresler 4.\" All rights reserved. 5.\" Copyright (c) 2023-2024 The FreeBSD Foundation 6.\" 7.\" Portions of this documentation were written by Mitchell Horne 8.\" under sponsorship from the FreeBSD Foundation. 9.\" 10.\" This program is free software. 11.\" 12.\" Redistribution and use in source and binary forms, with or without 13.\" modification, are permitted provided that the following conditions 14.\" are met: 15.\" 1. Redistributions of source code must retain the above copyright 16.\" notice, this list of conditions and the following disclaimer. 17.\" 2. Redistributions in binary form must reproduce the above copyright 18.\" notice, this list of conditions and the following disclaimer in the 19.\" documentation and/or other materials provided with the distribution. 20.\" 21.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 22.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 25.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31.\" 32.Dd March 19, 2024 33.Dt KASSERT 9 34.Os 35.Sh NAME 36.Nm KASSERT 37.Nd kernel expression verification macros 38.Sh SYNOPSIS 39.Cd "options INVARIANTS" 40.Pp 41.In sys/param.h 42.In sys/systm.h 43.Fn KASSERT expression msg 44.Fn MPASS expression 45.Sh DESCRIPTION 46Assertions are widely used within the 47.Fx 48kernel to verify programmatic assumptions. 49For violations of run-time assumptions and invariants, it is desirable to fail 50as soon and as loudly as possible. 51Assertions are optional code; for non-recoverable error conditions an explicit 52call to 53.Xr panic 9 54is usually preferred. 55.Pp 56The 57.Fn KASSERT 58macro tests the given boolean 59.Fa expression . 60If 61.Fa expression 62evaluates to 63.Dv false , 64and the kernel is compiled with 65.Cd "options INVARIANTS" , 66the 67.Xr panic 9 68function is called. 69This terminates the running system at the point of the error, possibly dropping 70into the kernel debugger or initiating a kernel core dump. 71The second argument, 72.Fa msg , 73is a 74.Xr printf 9 75format string and its arguments, 76enclosed in parentheses. 77The formatted string will become the panic string. 78.Pp 79In a kernel that is built without 80.Cd "options INVARIANTS" , 81the assertion macros are defined to be no-ops. 82This eliminates the runtime overhead of widespread assertions from release 83builds of the kernel. 84Therefore, checks which can be performed in a constant amount of time can be 85added as assertions without concern about their performance impact. 86More expensive checks, such as those that output to console, or verify the 87integrity of a chain of objects are generally best hidden behind the 88.Cd DIAGNOSTIC 89kernel option. 90.Pp 91The 92.Fn MPASS 93macro (read as: "must-pass") 94is a convenience wrapper around 95.Fn KASSERT 96that automatically generates a simple assertion message including file and line 97information. 98.Ss Assertion Guidelines 99When adding new assertions, keep in mind their primary purpose: to aid in 100identifying and debugging of complex error conditions. 101.Pp 102The panic messages resulting from assertion failures should be useful without 103the resulting kernel dump; the message may be included in a bug report, and 104should contain the relevant information needed to discern how the assertion was 105violated. 106This is especially important when the error condition is difficult or 107impossible for the developer to reproduce locally. 108.Pp 109Therefore, assertions should adhere to the following guidelines: 110.Bl -enum 111.It 112Whenever possible, the value of a runtime variable checked by an assertion 113condition should appear in its message. 114.It 115Unrelated conditions must appear in separate assertions. 116.It 117Multiple related conditions should be distinguishable (e.g. by value), or split 118into separate assertions. 119.It 120When in doubt, print more information, not less. 121.El 122.Pp 123Combined, this gives greater clarity into the exact cause of an assertion 124panic; see 125.Sx EXAMPLES 126below. 127.Sh EXAMPLES 128A hypothetical 129.Vt struct foo 130object must not have its 'active' flag set when calling 131.Fn foo_dealloc : 132.Bd -literal -offset indent 133void 134foo_dealloc(struct foo *fp) 135{ 136 137 KASSERT((fp->foo_flags & FOO_ACTIVE) == 0, 138 ("%s: fp %p is still active, flags=%x", __func__, fp, 139 fp->foo_flags)); 140 ... 141} 142.Ed 143.Pp 144This assertion provides the full flag set for the object, as well as the memory 145pointer, which may be used by a debugger to examine the object in detail 146.Po 147for example with a 'show foo' command in 148.Xr ddb 4 149.Pc . 150.Pp 151The assertion 152.Bd -literal -offset indent 153MPASS(td == curthread); 154.Ed 155.Pp 156located on line 87 of a file named foo.c would generate the following panic 157message: 158.Bd -literal -offset indent 159panic: Assertion td == curthread failed at foo.c:87 160.Ed 161.Pp 162This is a simple condition, and the message provides enough information to 163investigate the failure. 164.Pp 165The assertion 166.Bd -literal -offset indent 167MPASS(td == curthread && (sz >= SIZE_MIN && sz <= SIZE_MAX)); 168.Ed 169.Pp 170is 171.Em NOT 172useful enough. 173The message doesn't indicate which part of the assertion was violated, nor 174does it report the value of 175.Dv sz , 176which may be critical to understanding 177.Em why 178the assertion failed. 179.Pp 180According to the guidelines above, this would be correctly expressed as: 181.Bd -literal -offset indent 182MPASS(td == curthread); 183KASSERT(sz >= SIZE_MIN && sz <= SIZE_MAX, 184 ("invalid size argument: %u", sz)); 185.Ed 186.Sh HISTORY 187The 188.Nm MPASS 189macro first appeared in 190.Bsx 191and was imported into 192.Fx 5.0 . 193The name originates as an acronym of "multi-processor assert", but has evolved 194to mean "must pass", or "must-pass assert". 195.Sh SEE ALSO 196.Xr panic 9 197.Sh AUTHORS 198This manual page was written by 199.An Jonathan M. Bresler Aq Mt jmb@FreeBSD.org 200and 201.An Mitchell Horne Aq Mt mhorne@FreeBSD.org . 202