Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
KASSERT(9)		   Kernel Developer's Manual		    KASSERT(9)

NAME
       KASSERT -- kernel expression verification macros

SYNOPSIS
       options INVARIANTS

       #include	<sys/param.h>
       #include	<sys/systm.h>

       KASSERT(expression, msg);

       MPASS(expression);

DESCRIPTION
       Assertions are widely used within the FreeBSD kernel to verify program-
       matic  assumptions.  For	violations of run-time assumptions and invari-
       ants, it	is desirable to	fail as	soon and as loudly as  possible.   As-
       sertions	are optional code; for non-recoverable error conditions	an ex-
       plicit call to panic(9) is usually preferred.

       The  KASSERT() macro tests the given boolean expression.	 If expression
       evaluates to false, and the kernel is compiled with options INVARIANTS,
       the 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,  msg,  is a
       printf(9) format	string and its	arguments,  enclosed  in  parentheses.
       The formatted string will become	the panic string.

       In  a  kernel  that  is built without 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 ex-
       pensive checks, such as those that output to console, or	verify the in-
       tegrity	of  a  chain  of  objects are generally	best hidden behind the
       DIAGNOSTIC kernel option.

       The MPASS() macro (read	as:  "must-pass")  is  a  convenience  wrapper
       around  KASSERT()  that automatically generates a simple	assertion mes-
       sage including file and line information.

   Assertion Guidelines
       When adding new assertions, keep	in mind	their primary purpose: to  aid
       in identifying and debugging of complex error conditions.

       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	repro-
       duce locally.

       Therefore, assertions should adhere to the following guidelines:

       1.   Whenever  possible,	 the value of a	runtime	variable checked by an
	    assertion condition	should appear in its message.

       2.   Unrelated conditions must appear in	separate assertions.

       3.   Multiple related conditions	should	be  distinguishable  (e.g.  by
	    value), or split into separate assertions.

       4.   When in doubt, print more information, not less.

       Combined,  this gives greater clarity into the exact cause of an	asser-
       tion panic; see "EXAMPLES" below.

EXAMPLES
       A hypothetical struct foo object	must not have its  'active'  flag  set
       when calling foo_dealloc():

	     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));
		     ...
	     }

       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  ob-
       ject in detail (for example with	a 'show	foo' command in	ddb(4)).

       The assertion

	     MPASS(td == curthread);

       located	on  line 87 of a file named foo.c would	generate the following
       panic message:

	     panic: Assertion td == curthread failed at	foo.c:87

       This is a simple	condition, and the message provides enough information
       to investigate the failure.

       The assertion

	     MPASS(td == curthread && (sz >= SIZE_MIN && sz <= SIZE_MAX));

       is NOT useful enough.  The message doesn't indicate which part  of  the
       assertion  was  violated, nor does it report the	value of sz, which may
       be critical to understanding why	the assertion failed.

       According to the	guidelines above, this would  be  correctly  expressed
       as:

	     MPASS(td == curthread);
	     KASSERT(sz	>= SIZE_MIN && sz <= SIZE_MAX,
		 ("invalid size	argument: %u", sz));

HISTORY
       The  MPASS  macro  first	 appeared  in  BSD/OS  and  was	 imported into
       FreeBSD 5.0.  The name originates as an acronym of "multi-processor as-
       sert", but has evolved to mean "must pass", or "must-pass assert".

SEE ALSO
       panic(9)

AUTHORS
       This manual page	was written by Jonathan	M.  Bresler  <jmb@FreeBSD.org>
       and
       Mitchell	Horne <mhorne@FreeBSD.org>.

FreeBSD	14.3			March 19, 2024			    KASSERT(9)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=MPASS&sektion=9&manpath=FreeBSD+14.3-RELEASE+and+Ports>

home | help