1 // Copyright 2020 The Pigweed Authors 2 // 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 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 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 13 // the License. 14 // ============================================================================= 15 // 16 // This file describes Pigweed's public user-facing assert API. 17 // 18 // THIS API IS NOT STABLE OR COMPLETE! NEITHER FACADE NOR BACKEND API! 19 // 20 #pragma once 21 22 #include "pw_preprocessor/arguments.h" 23 24 // The pw_assert public API: 25 // 26 // Trigger a crash with a message. Replaces LOG_FATAL() in other systems. 27 // PW_CRASH(msg, ...) 28 // 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) 32 // 33 // Asserts the condition, crashes on failure. Equivalent to assert. 34 // PW_CHECK(condition) or 35 // PW_CHECK(condition, msg, ...) 36 // 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 40 // 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. 44 // 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 52 // 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 60 // 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 68 // 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 78 // 79 // Integer-overflow asserts for integer types: 80 // PW_CHECK_ADD(a, b, out, msg, ...) 81 // Asserts a + b does not overflow and stores the result in out. 82 // PW_CHECK_SUB(a, b, out, msg, ...) 83 // Asserts a - b does not overflow and stores the result in out. 84 // PW_CHECK_MUL(a, b, out, msg, ...) 85 // Asserts a * b does not overflow and stores the result in out. 86 // 87 // The above CHECK_*_*() are also available in DCHECK variants, which will 88 // only evaluate their arguments and trigger if the NDEBUG macro is defined. 89 // 90 // Note: For float, proper comparator checks which take floating point 91 // precision and ergo error accumulation into account are not provided on 92 // purpose as this comes with some complexity and requires application 93 // specific tolerances in terms of Units of Least Precision (ULP). Instead, 94 // carefully consider how floating point precision and error impact the data 95 // they are bounding and whether CHECKs are appropriate. 96 // 97 // Note: PW_CRASH is the equivalent of LOG_FATAL in other systems, where a 98 // device crash is triggered with a message. In Pigweed, logging and 99 // crashing/asserting are separated. There is a LOG_CRITICAL level in the 100 // logging module, but it does not have side effects; for LOG_FATAL, instead 101 // use this macro (PW_CRASH). 102 // 103 // The public macro definitions are split out into an impl file to facilitate 104 // testing the facade logic directly, without going through the facade/backend 105 // build facilities. 106 #include "pw_assert/internal/check_impl.h" 107 108 // The pw_assert_backend must provide these macros: 109 // 110 // PW_HANDLE_CRASH(msg, ...) 111 // PW_HANDLE_ASSERT_FAILURE(condition, msg, ...) 112 // PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(a, op, b, type_fmt, msg, ...) 113 // 114 // The low level functionality of triggering a crash, rebooting a device, 115 // collecting information, or hanging out in a while(1) loop, must be 116 // provided by the underlying assert backend as part of the crash or assert 117 // failure handling. 118 // 119 // Note that for the assert failures, the handler should assume the assert 120 // has already failed (the facade checks the condition before delegating). 121 // 122 #include "pw_assert_backend/check_backend.h" 123