1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
14 // =============================================================================
16 // This file describes Pigweed's public user-facing assert API.
18 // THIS API IS NOT STABLE OR COMPLETE! NEITHER FACADE NOR BACKEND API!
22 #include "pw_preprocessor/arguments.h"
24 // The pw_assert public API:
26 // Trigger a crash with a message. Replaces LOG_FATAL() in other systems.
29 // In all below cases, the message argument is optional:
30 // PW_CHECK_INT_LE(x, y) or
31 // PW_CHECK_INT_LE(x, y, "Was booting %s subsystem", subsystem_name)
33 // Asserts the condition, crashes on failure. Equivalent to assert.
34 // PW_CHECK(condition) or
35 // PW_CHECK(condition, msg, ...)
37 // Some common typed checks.
38 // PW_CHECK_OK(status, msg, ...) Asserts status == PW_STATUS_OK
39 // PW_CHECK_NOTNULL(ptr, msg, ...) Asserts ptr != NULL
41 // In many cases an assert is a binary comparison. In those cases, using the
42 // special binary assert macros below for <, <=, >, >=, == enables reporting
43 // the values of the operands in addition to the string of the condition.
45 // Binary comparison asserts for 'int' type ("%d" in format strings):
46 // PW_CHECK_INT_LE(a, b, msg, ...) Asserts a <= b
47 // PW_CHECK_INT_LT(a, b, msg, ...) Asserts a < b
48 // PW_CHECK_INT_GE(a, b, msg, ...) Asserts a >= b
49 // PW_CHECK_INT_GT(a, b, msg, ...) Asserts a > b
50 // PW_CHECK_INT_EQ(a, b, msg, ...) Asserts a == b
51 // PW_CHECK_INT_NE(a, b, msg, ...) Asserts a != b
53 // Binary comparison asserts for 'unsigned int' type ("%u" in format strings):
54 // PW_CHECK_UINT_LE(a, b, msg, ...) Asserts a <= b
55 // PW_CHECK_UINT_LT(a, b, msg, ...) Asserts a < b
56 // PW_CHECK_UINT_GE(a, b, msg, ...) Asserts a >= b
57 // PW_CHECK_UINT_GT(a, b, msg, ...) Asserts a > b
58 // PW_CHECK_UINT_EQ(a, b, msg, ...) Asserts a == b
59 // PW_CHECK_UINT_NE(a, b, msg, ...) Asserts a != b
61 // Binary comparison asserts for 'void*' type ("%p" in format strings):
62 // PW_CHECK_PTR_LE(a, b, msg, ...) Asserts a <= b
63 // PW_CHECK_PTR_LT(a, b, msg, ...) Asserts a < b
64 // PW_CHECK_PTR_GE(a, b, msg, ...) Asserts a >= b
65 // PW_CHECK_PTR_GT(a, b, msg, ...) Asserts a > b
66 // PW_CHECK_PTR_EQ(a, b, msg, ...) Asserts a == b
67 // PW_CHECK_PTR_NE(a, b, msg, ...) Asserts a != b
69 // Binary comparison asserts for 'float' type ("%f" in format strings):
70 // PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance, msg, ...)
71 // Asserts (a >= (b - abs_tolerance)) && (a <= (b + abs_tolerance))
72 // PW_CHECK_FLOAT_EXACT_LE(a, b, msg, ...) Asserts a <= b
73 // PW_CHECK_FLOAT_EXACT_LT(a, b, msg, ...) Asserts a < b
74 // PW_CHECK_FLOAT_EXACT_GE(a, b, msg, ...) Asserts a >= b
75 // PW_CHECK_FLOAT_EXACT_GT(a, b, msg, ...) Asserts a > b
76 // PW_CHECK_FLOAT_EXACT_EQ(a, b, msg, ...) Asserts a == b
77 // PW_CHECK_FLOAT_EXACT_NE(a, b, msg, ...) Asserts a != b
79 // The above CHECK_*_*() are also available in DCHECK variants, which will
80 // only evaluate their arguments and trigger if the NDEBUG macro is defined.
82 // Note: For float, proper comparator checks which take floating point
83 // precision and ergo error accumulation into account are not provided on
84 // purpose as this comes with some complexity and requires application
85 // specific tolerances in terms of Units of Least Precision (ULP). Instead,
86 // we recommend developers carefully consider how floating point precision and
87 // error impact the data they are bounding and whether CHECKs are appropriate.
89 // Note: PW_CRASH is the equivalent of LOG_FATAL in other systems, where a
90 // device crash is triggered with a message. In Pigweed, logging and
91 // crashing/asserting are separated. There is a LOG_CRITICAL level in the
92 // logging module, but it does not have side effects; for LOG_FATAL, instead
93 // use this macro (PW_CRASH).
95 // The public macro definitions are split out into an impl file to facilitate
96 // testing the facade logic directly, without going through the facade/backend
98 #include "pw_assert/internal/assert_impl.h"
100 // The pw_assert_backend must provide these macros:
102 // PW_HANDLE_CRASH(msg, ...)
103 // PW_HANDLE_ASSERT_FAILURE(condition, msg, ...)
104 // PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(a, op, b, type_fmt, msg, ...)
106 // The low level functionality of triggering a crash, rebooting a device,
107 // collecting information, or hanging out in a while(1) loop, must be
108 // provided by the underlying assert backend as part of the crash or assert
111 // Note that for the assert failures, the handler should assume the assert
112 // has already failed (the facade checks the condition before delegating).
114 #include "pw_assert_backend/assert_backend.h"