mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-26 04:54:07 +01:00
5d956e11ed
The macro originates from BSD/OS, with a different etymology than what is presented. Add a brief HISTORY section to capture this. Reviewed by: emaste MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D44439
202 lines
6.1 KiB
Groff
202 lines
6.1 KiB
Groff
.\" SPDX-License-Identifier: BSD-2-Clause
|
|
.\"
|
|
.\" Copyright (c) 2000 Jonathan M. Bresler
|
|
.\" All rights reserved.
|
|
.\" Copyright (c) 2023-2024 The FreeBSD Foundation
|
|
.\"
|
|
.\" Portions of this documentation were written by Mitchell Horne
|
|
.\" under sponsorship from the FreeBSD Foundation.
|
|
.\"
|
|
.\" This program is free software.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd March 19, 2024
|
|
.Dt KASSERT 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm KASSERT
|
|
.Nd kernel expression verification macros
|
|
.Sh SYNOPSIS
|
|
.Cd "options INVARIANTS"
|
|
.Pp
|
|
.In sys/param.h
|
|
.In sys/systm.h
|
|
.Fn KASSERT expression msg
|
|
.Fn MPASS expression
|
|
.Sh DESCRIPTION
|
|
Assertions are widely used within the
|
|
.Fx
|
|
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
|
|
.Xr panic 9
|
|
is usually preferred.
|
|
.Pp
|
|
The
|
|
.Fn KASSERT
|
|
macro tests the given boolean
|
|
.Fa expression .
|
|
If
|
|
.Fa expression
|
|
evaluates to
|
|
.Dv false ,
|
|
and the kernel is compiled with
|
|
.Cd "options INVARIANTS" ,
|
|
the
|
|
.Xr panic 9
|
|
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,
|
|
.Fa msg ,
|
|
is a
|
|
.Xr printf 9
|
|
format string and its arguments,
|
|
enclosed in parentheses.
|
|
The formatted string will become the panic string.
|
|
.Pp
|
|
In a kernel that is built without
|
|
.Cd "options INVARIANTS" ,
|
|
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
|
|
.Cd DIAGNOSTIC
|
|
kernel option.
|
|
.Pp
|
|
The
|
|
.Fn MPASS
|
|
macro (read as: "must-pass")
|
|
is a convenience wrapper around
|
|
.Fn KASSERT
|
|
that automatically generates a simple assertion message including file and line
|
|
information.
|
|
.Ss Assertion Guidelines
|
|
When adding new assertions, keep in mind their primary purpose: to aid in
|
|
identifying and debugging of complex error conditions.
|
|
.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.
|
|
.Pp
|
|
Therefore, assertions should adhere to the following guidelines:
|
|
.Bl -enum
|
|
.It
|
|
Whenever possible, the value of a runtime variable checked by an assertion
|
|
condition should appear in its message.
|
|
.It
|
|
Unrelated conditions must appear in separate assertions.
|
|
.It
|
|
Multiple related conditions should be distinguishable (e.g. by value), or split
|
|
into separate assertions.
|
|
.It
|
|
When in doubt, print more information, not less.
|
|
.El
|
|
.Pp
|
|
Combined, this gives greater clarity into the exact cause of an assertion
|
|
panic; see
|
|
.Sx EXAMPLES
|
|
below.
|
|
.Sh EXAMPLES
|
|
A hypothetical
|
|
.Vt struct foo
|
|
object must not have its 'active' flag set when calling
|
|
.Fn foo_dealloc :
|
|
.Bd -literal -offset indent
|
|
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));
|
|
...
|
|
}
|
|
.Ed
|
|
.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
|
|
.Po
|
|
for example with a 'show foo' command in
|
|
.Xr ddb 4
|
|
.Pc .
|
|
.Pp
|
|
The assertion
|
|
.Bd -literal -offset indent
|
|
MPASS(td == curthread);
|
|
.Ed
|
|
.Pp
|
|
located on line 87 of a file named foo.c would generate the following panic
|
|
message:
|
|
.Bd -literal -offset indent
|
|
panic: Assertion td == curthread failed at foo.c:87
|
|
.Ed
|
|
.Pp
|
|
This is a simple condition, and the message provides enough information to
|
|
investigate the failure.
|
|
.Pp
|
|
The assertion
|
|
.Bd -literal -offset indent
|
|
MPASS(td == curthread && (sz >= SIZE_MIN && sz <= SIZE_MAX));
|
|
.Ed
|
|
.Pp
|
|
is
|
|
.Em NOT
|
|
useful enough.
|
|
The message doesn't indicate which part of the assertion was violated, nor
|
|
does it report the value of
|
|
.Dv sz ,
|
|
which may be critical to understanding
|
|
.Em why
|
|
the assertion failed.
|
|
.Pp
|
|
According to the guidelines above, this would be correctly expressed as:
|
|
.Bd -literal -offset indent
|
|
MPASS(td == curthread);
|
|
KASSERT(sz >= SIZE_MIN && sz <= SIZE_MAX,
|
|
("invalid size argument: %u", sz));
|
|
.Ed
|
|
.Sh HISTORY
|
|
The
|
|
.Nm MPASS
|
|
macro first appeared in
|
|
.Bsx
|
|
and was imported into
|
|
.Fx 5.0 .
|
|
The name originates as an acronym of "multi-processor assert", but has evolved
|
|
to mean "must pass", or "must-pass assert".
|
|
.Sh SEE ALSO
|
|
.Xr panic 9
|
|
.Sh AUTHORS
|
|
This manual page was written by
|
|
.An Jonathan M. Bresler Aq Mt jmb@FreeBSD.org
|
|
and
|
|
.An Mitchell Horne Aq Mt mhorne@FreeBSD.org .
|