diff --git a/share/man/man9/KASSERT.9 b/share/man/man9/KASSERT.9 --- a/share/man/man9/KASSERT.9 +++ b/share/man/man9/KASSERT.9 @@ -40,7 +40,15 @@ .Pp .In sys/param.h .In sys/systm.h -.Fn KASSERT expression msg +.Fn KASSERT expression +.Fn KASSERT expression fmt ... +.Fo KASSERT +.Fa expression +.Ns , ( +.Fa fmt +.Fa ... +.Ns ) +.Ns Fc .Fn MPASS expression .Sh DESCRIPTION Assertions are widely used within the @@ -69,12 +77,23 @@ 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 , +.Fa fmt , is a .Xr printf 9 -format string and its arguments, -enclosed in parentheses. +format string followed by its arguments. The formatted string will become the panic string. +If no +.Fa fmt +argument is provided, a default string including the current file and line is used. +.Pp +The third form of +.Fn KASSERT +which encloses +.Fa fmt +and its arguments in a nested pair of parentheses is deprecated but must currently +been used when +.Fa fmt +does not accept additional arguments. .Pp In a kernel that is built without .Cd "options INVARIANTS" , @@ -135,8 +154,8 @@ { KASSERT((fp->foo_flags & FOO_ACTIVE) == 0, - ("%s: fp %p is still active, flags=%x", __func__, fp, - fp->foo_flags)); + "%s: fp %p is still active, flags=%x", __func__, fp, + fp->foo_flags); ... } .Ed @@ -150,7 +169,7 @@ .Pp The assertion .Bd -literal -offset indent -MPASS(td == curthread); +KASSERT(td == curthread); .Ed .Pp located on line 87 of a file named foo.c would generate the following panic @@ -179,11 +198,20 @@ .Pp According to the guidelines above, this would be correctly expressed as: .Bd -literal -offset indent -MPASS(td == curthread); +KASSERT(td == curthread); KASSERT(sz >= SIZE_MIN && sz <= SIZE_MAX, ("invalid size argument: %u", sz)); .Ed .Sh HISTORY +The third form of the +.Nm KASSERT +macro first appeared in +.Fx 3.0 . +The first and second forms of +.Nm KASSERT +macro first appeared in +.Fx 15.0 . +.Pp The .Nm MPASS macro first appeared in diff --git a/sys/sys/kassert.h b/sys/sys/kassert.h --- a/sys/sys/kassert.h +++ b/sys/sys/kassert.h @@ -146,12 +146,30 @@ * Kernel assertion; see KASSERT(9) for details. */ #if (defined(_KERNEL) && defined(INVARIANTS)) || defined(_STANDALONE) -#define KASSERT(exp,msg) do { \ +#define KASSERTN(exp, ...) do { \ + if (__predict_false(!(exp))) \ + kassert_panic(__VA_ARGS__); \ +} while (0) +#define KASSERT2(exp, msg) do { \ if (__predict_false(!(exp))) \ kassert_panic msg; \ } while (0) +#define KASSERT1(exp) do { \ + if (__predict_false(!(exp))) \ + kassert_panic("Assertion %s failed at %s:%d", #exp, \ + __FILE__, __LINE__); \ +} while (0) + +#define _KASSERT_MACRO(exp, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + NAME, ...) \ + NAME + +#define KASSERT(...) \ + _KASSERT_MACRO(__VA_ARGS__, KASSERTN, KASSERTN, KASSERTN, \ + KASSERTN, KASSERTN, KASSERTN, KASSERTN, KASSERTN, KASSERTN, \ + KASSERT2, KASSERT1)(__VA_ARGS__) #else /* !(KERNEL && INVARIANTS) && !_STANDALONE */ -#define KASSERT(exp,msg) do { \ +#define KASSERT(...) do { \ } while (0) #endif /* (_KERNEL && INVARIANTS) || _STANDALONE */ @@ -167,7 +185,7 @@ #define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) #define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) #define MPASS4(ex, what, file, line) \ - KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) + KASSERT((ex), "Assertion %s failed at %s:%d", what, file, line) /* * Assert that a pointer can be loaded from memory atomically.