blob: c181416cdac33cafc9411edfd276db6882ba7916 [file] [log] [blame]
Keir Mierle3cee8792020-01-22 17:08:13 -08001.. _chapter-pw-assert:
2
3.. default-domain:: cpp
4
5.. highlight:: cpp
6
Keir Mierleec9bf1b2020-03-03 10:27:01 -08007=========
Keir Mierle3cee8792020-01-22 17:08:13 -08008pw_assert
Keir Mierleec9bf1b2020-03-03 10:27:01 -08009=========
10
11--------
12Overview
13--------
Keir Mierle3cee8792020-01-22 17:08:13 -080014Pigweed's assert module provides facilities for applications to check
Keir Mierleec9bf1b2020-03-03 10:27:01 -080015preconditions. The module is split into two components:
Keir Mierle3cee8792020-01-22 17:08:13 -080016
171. The facade (this module) which is only a macro interface layer
182. The backend, provided elsewhere, that implements the low level checks
19
Keir Mierleec9bf1b2020-03-03 10:27:01 -080020All behaviour is controlled by the backend.
21
22The ``pw_assert`` public API provides three classes of macros:
23
24+-----------------------------------------+--------------------------------+
25| PW_CRASH(format, ...) | Trigger a crash with a message |
26+-----------------------------------------+--------------------------------+
27| PW_CHECK(condition[, format, ...]) | Assert a condition, optionally |
28| | with a message |
29+-----------------------------------------+--------------------------------+
30| PW_CHECK_<type>_<cmp>(a, b[, fmt, ...]) | Assert that the expression |
31| | ``a <cmp> b`` is true, |
32| | optionally with a message. |
33+-----------------------------------------+--------------------------------+
34
35.. tip::
36 All of the assert macros optionally support a message with additional
37 arguments, to assist in debugging when an assert triggers:
38
39 .. code-block:: cpp
40
41 PW_CHECK_INT_LE(ItemCount(), 100);
42 PW_CHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr());
43
44Compatibility
45-------------
46The facade is compatible with C and C++.
47
48Example
49-------
Keir Mierle3cee8792020-01-22 17:08:13 -080050
51.. code-block:: cpp
52
53 #include "pw_assert/assert.h"
54
55 int main() {
56 bool sensor_running = StartSensor(&msg);
57 PW_CHECK(sensor_running, "Sensor failed to start; code: %s", msg);
Keir Mierleec9bf1b2020-03-03 10:27:01 -080058
59 int temperature_c = ReadSensorCelcius();
60 PW_CHECK_INT_LE(temperature_c, 100,
61 "System is way out of heat spec; state=%s",
62 ReadSensorStateString());
Keir Mierle3cee8792020-01-22 17:08:13 -080063 }
64
Keir Mierleec9bf1b2020-03-03 10:27:01 -080065
66---------------------------
67Assert facade API reference
68---------------------------
69
70The below functions describe the assert API functions that applications should
71invoke to assert.
72
73.. cpp:function:: PW_CRASH(format, ...)
74
75 Trigger a crash with a message. Replaces LOG_FATAL() in other systems. Can
76 include a message with format arguments; for example:
77
78 .. code-block:: cpp
79
80 PW_CRASH("Unexpected: frobnitz in state: %s", frobnitz_state);
81
82 Note: ``PW_CRASH`` is the equivalent of ``LOG_FATAL`` in other systems, where
83 a device crash is triggered with a message. In Pigweed, logging and
84 crashing/asserting are separated. There is a ``LOG_CRITICAL`` level in the
85 logging module, but it does not have side effects; for ``LOG_FATAL``, instead
86 use this macro (``PW_CRASH``).
87
88.. cpp:function:: PW_CHECK(condition)
89.. cpp:function:: PW_CHECK(condition, format, ...)
90
91 Assert that a condition is true, optionally including a message with
92 arguments to report if the codition is false.
93
94 .. code-block:: cpp
95
96 PW_CHECK(StartTurbines());
97 PW_CHECK(StartWarpDrive(), "Oddly warp drive couldn't start; ruh-roh!");
98
99.. cpp:function:: PW_CHECK_TYPE_OP(a, b)
100.. cpp:function:: PW_CHECK_TYPE_OP(a, b, format, ...)
101
102 Asserts that ``a OP b`` is true, where ``a`` and ``b`` are converted to
103 ``TYPE``; with ``OP`` and ``TYPE`` described below.
104
105 If present, the optional format message is reported on failure. Depending on
106 the backend, values of ``a`` and ``b`` will also be reported.
107
108 Example, with no message:
109
110 .. code-block:: cpp
111
112 PW_CHECK_INT_LE(CurrentTemperature(), 100);
113 PW_CHECK_INT_LE(ItemCount(), 100);
114
115 Example, with an included message and arguments:
116
117 .. code-block:: cpp
118
119 PW_CHECK_FLOAT_GE(BatteryVoltage(), 3.2, "System state=%s", SysState());
120
121 Below is the full list of binary comparison assert macros, along with the
122 type specifier. The specifier is irrelevant to application authors but is
123 needed for backend implementers.
124
125 +-------------------+--------------+-----------+-----------------------+
126 | Macro | a, b type | condition | a, b format specifier |
127 +-------------------+--------------+-----------+-----------------------+
128 | PW_CHECK_INT_LE | int | a <= b | %d |
129 +-------------------+--------------+-----------+-----------------------+
130 | PW_CHECK_INT_LT | int | a < b | %d |
131 +-------------------+--------------+-----------+-----------------------+
132 | PW_CHECK_INT_GE | int | a >= b | %d |
133 +-------------------+--------------+-----------+-----------------------+
134 | PW_CHECK_INT_GT | int | a > b | %d |
135 +-------------------+--------------+-----------+-----------------------+
136 | PW_CHECK_INT_EQ | int | a == b | %d |
137 +-------------------+--------------+-----------+-----------------------+
138 | PW_CHECK_UINT_LE | unsigned int | a <= b | %u |
139 +-------------------+--------------+-----------+-----------------------+
140 | PW_CHECK_UINT_LT | unsigned int | a < b | %u |
141 +-------------------+--------------+-----------+-----------------------+
142 | PW_CHECK_UINT_GE | unsigned int | a >= b | %u |
143 +-------------------+--------------+-----------+-----------------------+
144 | PW_CHECK_UINT_GT | unsigned int | a > b | %u |
145 +-------------------+--------------+-----------+-----------------------+
146 | PW_CHECK_UINT_EQ | unsigned int | a == b | %u |
147 +-------------------+--------------+-----------+-----------------------+
148 | PW_CHECK_FLOAT_LE | float | a <= b | %f |
149 +-------------------+--------------+-----------+-----------------------+
150 | PW_CHECK_FLOAT_LT | float | a < b | %f |
151 +-------------------+--------------+-----------+-----------------------+
152 | PW_CHECK_FLOAT_GE | float | a >= b | %f |
153 +-------------------+--------------+-----------+-----------------------+
154 | PW_CHECK_FLOAT_GT | float | a > b | %f |
155 +-------------------+--------------+-----------+-----------------------+
156 | PW_CHECK_FLOAT_EQ | float | a == b | %f |
157 +-------------------+--------------+-----------+-----------------------+
158
159----------------------------
160Assert backend API reference
161----------------------------
162
163The backend controls what to do in the case of an assertion failure. In the
164most basic cases, the backend could display the assertion failure on something
165like sys_io and halt in a while loop waiting for a debugger. In other cases,
166the backend could store crash details like the current thread's stack to flash.
167
168This module does not provide a backend; see ``pw_assert_basic`` for a basic
169implementation (which we do not advise using in production).
170
171Here are the macros the backend must provide:
172
173.. cpp:function:: PW_HANDLE_CRASH(message, ...)
174
175 The backend should trigger a system crash or halt, and if possible, deliver
176 the specified message and arguments to the user or developer.
177
178.. cpp:function:: PW_HANDLE_ASSERT_FAILURE(condition_str, message, ...)
179
180 This macro is invoked from ``PW_CHECK`` if condition is false. The
181 application should crash with the given message and specified format
182 arguments, and may optionally include the stringified condition provided in
183 ``condition_str``.
184
185.. cpp:function:: PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \
186 a_str, a_val, op_str, b_str, b_val, type_fmt, message, ...)
187
188 This macro is invoked from the ``PW_CHECK_*_*`` macros if the condition
189 ``a_val op b_val`` is false. The facade API macros have already evaluated and
190 stringified the arguments, so the backend is free to report the details as
191 needed.
192
193 The backend is expected to report the failure to the user or developer in a
194 useful way, potentially capturing the string and values of the binary
195 comparison operands.