blob: aa43ca53f0dded2f86a817a1f2fe21c2397c9180 [file] [log] [blame]
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -07001.. _module-pw_assert:
Keir Mierle3cee8792020-01-22 17:08:13 -08002
Keir Mierleec9bf1b2020-03-03 10:27:01 -08003=========
Keir Mierle3cee8792020-01-22 17:08:13 -08004pw_assert
Keir Mierleec9bf1b2020-03-03 10:27:01 -08005=========
6
7--------
8Overview
9--------
Keir Mierle481d8292020-07-31 01:10:05 -070010Pigweed's assert module enables applications to check preconditions, triggering
11a crash if the condition is not met. Consistent use of asserts is one aspect of
12defensive programming that can lead to more reliable and less buggy code.
Keir Mierle3cee8792020-01-22 17:08:13 -080013
Keir Mierle481d8292020-07-31 01:10:05 -070014The assert API facilitates flexible crash handling through Pigweed's facade
Shiva Rajagopal9e516562021-05-11 17:04:15 -070015mechanism. The API is designed to enable features like:
Keir Mierle3cee8792020-01-22 17:08:13 -080016
Keir Mierle481d8292020-07-31 01:10:05 -070017- Optional ancillary printf-style messages along assertions
18- Capturing actual values of binary operator assertions like ``a < b``
19- Compatibility with pw_tokenizer for reduced binary code size
Keir Mierleec9bf1b2020-03-03 10:27:01 -080020
Keir Mierle481d8292020-07-31 01:10:05 -070021The ``pw_assert`` API provides three classes of macros:
Keir Mierleec9bf1b2020-03-03 10:27:01 -080022
Keir Mierle481d8292020-07-31 01:10:05 -070023- **PW_CRASH(format, ...)** - Trigger a crash with a message.
24- **PW_CHECK(condition[, format, ...])** - Assert a condition, optionally with
25 a message.
26- **PW_CHECK_<type>_<cmp>(a, b[, fmt, ...])** - Assert that the expression ``a
27 <cmp> b`` is true, optionally with a message.
Wyatt Heplera59998f2021-03-19 14:35:10 -070028- **PW_ASSERT(condition)** - Header- and constexpr-safe assert.
Keir Mierleec9bf1b2020-03-03 10:27:01 -080029
30.. tip::
Keir Mierleb9b88162020-04-15 20:43:09 -070031
Wyatt Heplera59998f2021-03-19 14:35:10 -070032 All of the ``CHECK`` macros optionally support a message with additional
Keir Mierleec9bf1b2020-03-03 10:27:01 -080033 arguments, to assist in debugging when an assert triggers:
34
35 .. code-block:: cpp
36
37 PW_CHECK_INT_LE(ItemCount(), 100);
38 PW_CHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr());
39
Keir Mierleec9bf1b2020-03-03 10:27:01 -080040Example
41-------
Keir Mierle3cee8792020-01-22 17:08:13 -080042
43.. code-block:: cpp
44
Wyatt Heplera59998f2021-03-19 14:35:10 -070045 #include "pw_assert/check.h"
Keir Mierle3cee8792020-01-22 17:08:13 -080046
47 int main() {
48 bool sensor_running = StartSensor(&msg);
49 PW_CHECK(sensor_running, "Sensor failed to start; code: %s", msg);
Keir Mierleec9bf1b2020-03-03 10:27:01 -080050
51 int temperature_c = ReadSensorCelcius();
52 PW_CHECK_INT_LE(temperature_c, 100,
53 "System is way out of heat spec; state=%s",
54 ReadSensorStateString());
Keir Mierle3cee8792020-01-22 17:08:13 -080055 }
56
Keir Mierleb9b88162020-04-15 20:43:09 -070057.. tip::
58
59 All macros have both a ``CHECK`` and ``DCHECK`` variant. The ``CHECK``
60 variant is always enabled, even in production. Generally, we advise making
61 most asserts ``CHECK`` rather than ``DCHECK``, unless there is a critical
62 performance or code size reason to use ``DCHECK``.
63
64 .. code-block:: cpp
65
66 // This assert is always enabled, even in production.
67 PW_CHECK_INT_LE(ItemCount(), 100);
68
69 // This assert disabled for release builds, where NDEBUG is defined.
70 // The functions ItemCount() and GetStateStr() are never called.
71 PW_DCHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr());
Keir Mierleec9bf1b2020-03-03 10:27:01 -080072
Keir Mierle854adec2020-09-03 14:07:19 -070073.. tip::
74
Wyatt Heplera59998f2021-03-19 14:35:10 -070075 Use ``PW_ASSERT`` from ``pw_assert/assert.h`` for asserts in headers or
Keir Mierle854adec2020-09-03 14:07:19 -070076 asserting in ``constexpr`` contexts.
77
Keir Mierle481d8292020-07-31 01:10:05 -070078Structure of assert modules
79---------------------------
80The module is split into two components:
81
821. The **facade** (this module) which is only a macro interface layer, and
83 performs the actual checks for the conditions.
842. The **backend**, provided elsewhere, that handles the consequences of an
85 assert failing. Example backends include ``pw_assert_basic``, which prints a
86 useful message and either quits the application (on host) or hangs in a
87 while loop (on device). In the future, there will be a tokenized assert
88 backend. This is also where application or product specific crash handling
89 would go.
90
91.. blockdiag::
92
93 blockdiag {
94 default_fontsize = 16;
95 facade [label = "facade"];
96 backend [label = "backend"];
97 facade -> backend
98 }
99
100See the Backend API section below for more details.
101
Keir Mierle854adec2020-09-03 14:07:19 -0700102----------
103Facade API
104----------
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800105The below functions describe the assert API functions that applications should
Wyatt Heplera59998f2021-03-19 14:35:10 -0700106invoke to assert. These macros are found in the ``pw_assert/check.h`` header.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800107
108.. cpp:function:: PW_CRASH(format, ...)
109
110 Trigger a crash with a message. Replaces LOG_FATAL() in other systems. Can
111 include a message with format arguments; for example:
112
113 .. code-block:: cpp
114
115 PW_CRASH("Unexpected: frobnitz in state: %s", frobnitz_state);
116
117 Note: ``PW_CRASH`` is the equivalent of ``LOG_FATAL`` in other systems, where
118 a device crash is triggered with a message. In Pigweed, logging and
119 crashing/asserting are separated. There is a ``LOG_CRITICAL`` level in the
120 logging module, but it does not have side effects; for ``LOG_FATAL``, instead
121 use this macro (``PW_CRASH``).
122
123.. cpp:function:: PW_CHECK(condition)
124.. cpp:function:: PW_CHECK(condition, format, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700125.. cpp:function:: PW_DCHECK(condition)
126.. cpp:function:: PW_DCHECK(condition, format, ...)
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800127
128 Assert that a condition is true, optionally including a message with
129 arguments to report if the codition is false.
130
Keir Mierleb9b88162020-04-15 20:43:09 -0700131 The ``DCHECK`` variants only run if ``NDEBUG`` is defined; otherwise, the
132 entire statement is removed (and the expression not evaluated).
133
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700134 Example:
135
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800136 .. code-block:: cpp
137
138 PW_CHECK(StartTurbines());
139 PW_CHECK(StartWarpDrive(), "Oddly warp drive couldn't start; ruh-roh!");
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700140 PW_CHECK(RunSelfTest(), "Failure in self test; try %d", TestAttempts());
141
142 .. attention::
143
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700144 Don't use use ``PW_CHECK`` for binary comparisons or status checks!
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700145
146 Instead, use the ``PW_CHECK_<TYPE>_<OP>`` macros. These macros enable
147 capturing the value of the operands, and also tokenizing them if using a
148 tokenizing assert backend. For example, if ``x`` and ``b`` are integers,
149 use instead ``PW_CHECK_INT_LT(x, b)``.
150
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800151 Additionally, use ``PW_CHECK_OK(status)`` when checking for an OK status,
152 since it enables showing a human-readable status string rather than an
153 integer (e.g. ``status == RESOURCE_EXHAUSTED`` instead of ``status == 5``.
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700154
155 +------------------------------------+-------------------------------------+
156 | **Do NOT do this** | **Do this instead** |
157 +------------------------------------+-------------------------------------+
158 | ``PW_CHECK(a_int < b_int)`` | ``PW_CHECK_INT_LT(a_int, b_int)`` |
159 +------------------------------------+-------------------------------------+
160 | ``PW_CHECK(a_ptr <= b_ptr)`` | ``PW_CHECK_PTR_LE(a_ptr, b_ptr)`` |
161 +------------------------------------+-------------------------------------+
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700162 | ``PW_CHECK(Temp() <= 10.0)`` | ``PW_CHECK_FLOAT_EXACT_LE(`` |
163 | | `` Temp(), 10.0)`` |
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700164 +------------------------------------+-------------------------------------+
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800165 | ``PW_CHECK(Foo() == OkStatus())`` | ``PW_CHECK_OK(Foo())`` |
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700166 +------------------------------------+-------------------------------------+
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800167
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700168.. cpp:function:: PW_CHECK_NOTNULL(ptr)
169.. cpp:function:: PW_CHECK_NOTNULL(ptr, format, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700170.. cpp:function:: PW_DCHECK_NOTNULL(ptr)
171.. cpp:function:: PW_DCHECK_NOTNULL(ptr, format, ...)
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700172
173 Assert that the given pointer is not ``NULL``, optionally including a message
174 with arguments to report if the pointer is ``NULL``.
175
Keir Mierleb9b88162020-04-15 20:43:09 -0700176 The ``DCHECK`` variants only run if ``NDEBUG`` is defined; otherwise, the
177 entire statement is removed (and the expression not evaluated).
178
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700179 .. code-block:: cpp
180
181 Foo* foo = GetTheFoo()
182 PW_CHECK_NOTNULL(foo);
183
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700184 Bar* bar = GetSomeBar();
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700185 PW_CHECK_NOTNULL(bar, "Weirdly got NULL bar; state: %d", MyState());
186
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800187.. cpp:function:: PW_CHECK_TYPE_OP(a, b)
188.. cpp:function:: PW_CHECK_TYPE_OP(a, b, format, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700189.. cpp:function:: PW_DCHECK_TYPE_OP(a, b)
190.. cpp:function:: PW_DCHECK_TYPE_OP(a, b, format, ...)
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800191
192 Asserts that ``a OP b`` is true, where ``a`` and ``b`` are converted to
193 ``TYPE``; with ``OP`` and ``TYPE`` described below.
194
195 If present, the optional format message is reported on failure. Depending on
196 the backend, values of ``a`` and ``b`` will also be reported.
197
Keir Mierleb9b88162020-04-15 20:43:09 -0700198 The ``DCHECK`` variants only run if ``NDEBUG`` is defined; otherwise, the
199 entire statement is removed (and the expression not evaluated).
200
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800201 Example, with no message:
202
203 .. code-block:: cpp
204
205 PW_CHECK_INT_LE(CurrentTemperature(), 100);
206 PW_CHECK_INT_LE(ItemCount(), 100);
207
208 Example, with an included message and arguments:
209
210 .. code-block:: cpp
211
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700212 PW_CHECK_FLOAT_EXACT_GE(BatteryVoltage(), 3.2,
213 "System state=%s", SysState());
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800214
215 Below is the full list of binary comparison assert macros, along with the
216 type specifier. The specifier is irrelevant to application authors but is
217 needed for backend implementers.
218
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700219 +-------------------------+--------------+-----------+-----------------------+
220 | Macro | a, b type | condition | a, b format specifier |
221 +-------------------------+--------------+-----------+-----------------------+
222 | PW_CHECK_INT_LE | int | a <= b | %d |
223 +-------------------------+--------------+-----------+-----------------------+
224 | PW_CHECK_INT_LT | int | a < b | %d |
225 +-------------------------+--------------+-----------+-----------------------+
226 | PW_CHECK_INT_GE | int | a >= b | %d |
227 +-------------------------+--------------+-----------+-----------------------+
228 | PW_CHECK_INT_GT | int | a > b | %d |
229 +-------------------------+--------------+-----------+-----------------------+
230 | PW_CHECK_INT_EQ | int | a == b | %d |
231 +-------------------------+--------------+-----------+-----------------------+
232 | PW_CHECK_INT_NE | int | a != b | %d |
233 +-------------------------+--------------+-----------+-----------------------+
234 | PW_CHECK_UINT_LE | unsigned int | a <= b | %u |
235 +-------------------------+--------------+-----------+-----------------------+
236 | PW_CHECK_UINT_LT | unsigned int | a < b | %u |
237 +-------------------------+--------------+-----------+-----------------------+
238 | PW_CHECK_UINT_GE | unsigned int | a >= b | %u |
239 +-------------------------+--------------+-----------+-----------------------+
240 | PW_CHECK_UINT_GT | unsigned int | a > b | %u |
241 +-------------------------+--------------+-----------+-----------------------+
242 | PW_CHECK_UINT_EQ | unsigned int | a == b | %u |
243 +-------------------------+--------------+-----------+-----------------------+
244 | PW_CHECK_UINT_NE | unsigned int | a != b | %u |
245 +-------------------------+--------------+-----------+-----------------------+
246 | PW_CHECK_PTR_LE | void* | a <= b | %p |
247 +-------------------------+--------------+-----------+-----------------------+
248 | PW_CHECK_PTR_LT | void* | a < b | %p |
249 +-------------------------+--------------+-----------+-----------------------+
250 | PW_CHECK_PTR_GE | void* | a >= b | %p |
251 +-------------------------+--------------+-----------+-----------------------+
252 | PW_CHECK_PTR_GT | void* | a > b | %p |
253 +-------------------------+--------------+-----------+-----------------------+
254 | PW_CHECK_PTR_EQ | void* | a == b | %p |
255 +-------------------------+--------------+-----------+-----------------------+
256 | PW_CHECK_PTR_NE | void* | a != b | %p |
257 +-------------------------+--------------+-----------+-----------------------+
258 | PW_CHECK_FLOAT_EXACT_LE | float | a <= b | %f |
259 +-------------------------+--------------+-----------+-----------------------+
260 | PW_CHECK_FLOAT_EXACT_LT | float | a < b | %f |
261 +-------------------------+--------------+-----------+-----------------------+
262 | PW_CHECK_FLOAT_EXACT_GE | float | a >= b | %f |
263 +-------------------------+--------------+-----------+-----------------------+
264 | PW_CHECK_FLOAT_EXACT_GT | float | a > b | %f |
265 +-------------------------+--------------+-----------+-----------------------+
266 | PW_CHECK_FLOAT_EXACT_EQ | float | a == b | %f |
267 +-------------------------+--------------+-----------+-----------------------+
268 | PW_CHECK_FLOAT_EXACT_NE | float | a != b | %f |
269 +-------------------------+--------------+-----------+-----------------------+
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800270
Keir Mierleb9b88162020-04-15 20:43:09 -0700271 The above ``CHECK_*_*()`` are also available in DCHECK variants, which will
272 only evaluate their arguments and trigger if the ``NDEBUG`` macro is defined.
273
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700274 +--------------------------+--------------+-----------+----------------------+
275 | Macro | a, b type | condition | a, b format |
276 | | | | specifier |
277 +--------------------------+--------------+-----------+----------------------+
278 | PW_DCHECK_INT_LE | int | a <= b | %d |
279 +--------------------------+--------------+-----------+----------------------+
280 | PW_DCHECK_INT_LT | int | a < b | %d |
281 +--------------------------+--------------+-----------+----------------------+
282 | PW_DCHECK_INT_GE | int | a >= b | %d |
283 +--------------------------+--------------+-----------+----------------------+
284 | PW_DCHECK_INT_GT | int | a > b | %d |
285 +--------------------------+--------------+-----------+----------------------+
286 | PW_DCHECK_INT_EQ | int | a == b | %d |
287 +--------------------------+--------------+-----------+----------------------+
288 | PW_DCHECK_INT_NE | int | a != b | %d |
289 +--------------------------+--------------+-----------+----------------------+
290 | PW_DCHECK_UINT_LE | unsigned int | a <= b | %u |
291 +--------------------------+--------------+-----------+----------------------+
292 | PW_DCHECK_UINT_LT | unsigned int | a < b | %u |
293 +--------------------------+--------------+-----------+----------------------+
294 | PW_DCHECK_UINT_GE | unsigned int | a >= b | %u |
295 +--------------------------+--------------+-----------+----------------------+
296 | PW_DCHECK_UINT_GT | unsigned int | a > b | %u |
297 +--------------------------+--------------+-----------+----------------------+
298 | PW_DCHECK_UINT_EQ | unsigned int | a == b | %u |
299 +--------------------------+--------------+-----------+----------------------+
300 | PW_DCHECK_UINT_NE | unsigned int | a != b | %u |
301 +--------------------------+--------------+-----------+----------------------+
302 | PW_DCHECK_PTR_LE | void* | a <= b | %p |
303 +--------------------------+--------------+-----------+----------------------+
304 | PW_DCHECK_PTR_LT | void* | a < b | %p |
305 +--------------------------+--------------+-----------+----------------------+
306 | PW_DCHECK_PTR_GE | void* | a >= b | %p |
307 +--------------------------+--------------+-----------+----------------------+
308 | PW_DCHECK_PTR_GT | void* | a > b | %p |
309 +--------------------------+--------------+-----------+----------------------+
310 | PW_DCHECK_PTR_EQ | void* | a == b | %p |
311 +--------------------------+--------------+-----------+----------------------+
312 | PW_DCHECK_PTR_NE | void* | a != b | %p |
313 +--------------------------+--------------+-----------+----------------------+
314 | PW_DCHECK_FLOAT_EXACT_LE | float | a <= b | %f |
315 +--------------------------+--------------+-----------+----------------------+
316 | PW_DCHECK_FLOAT_EXACT_LT | float | a < b | %f |
317 +--------------------------+--------------+-----------+----------------------+
318 | PW_DCHECK_FLOAT_EXACT_GE | float | a >= b | %f |
319 +--------------------------+--------------+-----------+----------------------+
320 | PW_DCHECK_FLOAT_EXACT_GT | float | a > b | %f |
321 +--------------------------+--------------+-----------+----------------------+
322 | PW_DCHECK_FLOAT_EXACT_EQ | float | a == b | %f |
323 +--------------------------+--------------+-----------+----------------------+
324 | PW_DCHECK_FLOAT_EXACT_NE | float | a != b | %f |
325 +--------------------------+--------------+-----------+----------------------+
326
327.. attention::
328
329 For float, proper comparator checks which take floating point
330 precision and ergo error accumulation into account are not provided on
331 purpose as this comes with some complexity and requires application
332 specific tolerances in terms of Units of Least Precision (ULP). Instead,
333 we recommend developers carefully consider how floating point precision and
334 error impact the data they are bounding and whether checks are appropriate.
335
336.. cpp:function:: PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance)
337.. cpp:function:: PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance, format, ...)
338.. cpp:function:: PW_DCHECK_FLOAT_NEAR(a, b, abs_tolerance)
339.. cpp:function:: PW_DCHECK_FLOAT_NEAR(a, b, abs_tolerance, format, ...)
340
341 Asserts that ``(a >= b - abs_tolerance) && (a <= b + abs_tolerance)`` is true,
342 where ``a``, ``b``, and ``abs_tolerance`` are converted to ``float``.
343
344 .. note::
345 This also asserts that ``abs_tolerance >= 0``.
346
347 The ``DCHECK`` variants only run if ``NDEBUG`` is defined; otherwise, the
348 entire statement is removed (and the expression not evaluated).
349
350 Example, with no message:
351
352 .. code-block:: cpp
353
354 PW_CHECK_FLOAT_NEAR(cos(0.0f), 1, 0.001);
355
356 Example, with an included message and arguments:
357
358 .. code-block:: cpp
359
360 PW_CHECK_FLOAT_NEAR(FirstOperation(), RedundantOperation(), 0.1,
361 "System state=%s", SysState());
Keir Mierleb9b88162020-04-15 20:43:09 -0700362
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700363.. cpp:function:: PW_CHECK_OK(status)
364.. cpp:function:: PW_CHECK_OK(status, format, ...)
365.. cpp:function:: PW_DCHECK_OK(status)
366.. cpp:function:: PW_DCHECK_OK(status, format, ...)
367
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800368 Assert that ``status`` evaluates to ``pw::OkStatus()`` (in C++) or
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700369 ``PW_STATUS_OK`` (in C). Optionally include a message with arguments to
370 report.
371
372 The ``DCHECK`` variants only run if ``NDEBUG`` is defined; otherwise, the
373 entire statement is removed (and the expression not evaluated).
374
375 .. code-block:: cpp
376
377 pw::Status operation_status = DoSomeOperation();
378 PW_CHECK_OK(operation_status);
379
380 // Any expression that evaluates to a pw::Status or pw_Status works.
381 PW_CHECK_OK(DoTheThing(), "System state: %s", SystemState());
382
383 // C works too.
384 pw_Status c_status = DoMoreThings();
385 PW_CHECK_OK(c_status, "System state: %s", SystemState());
386
387 .. note::
388
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800389 Using ``PW_CHECK_OK(status)`` instead of ``PW_CHECK(status == OkStatus())``
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700390 enables displaying an error message with a string version of the error
391 code; for example ``status == RESOURCE_EXHAUSTED`` instead of ``status ==
392 5``.
393
Wyatt Heplera59998f2021-03-19 14:35:10 -0700394----------
395Assert API
396----------
Keir Mierle854adec2020-09-03 14:07:19 -0700397The normal ``PW_CHECK_*`` and ``PW_DCHECK_*`` family of macros are intended to
398provide rich debug information, like the file, line number, value of operands
399in boolean comparisons, and more. However, this comes at a cost: these macros
400depend directly on the backend headers, and may perform complicated call-site
401transformations like tokenization.
402
403There are several issues with the normal ``PW_CHECK_*`` suite of macros:
404
4051. ``PW_CHECK_*`` in headers can cause ODR violations in the case of tokenized
406 asserts, due to differing module choices.
4072. ``PW_CHECK_*`` is not constexpr-safe.
4083. ``PW_CHECK_*`` can cause code bloat with some backends; this is the tradeoff
409 to get rich assert information.
4104. ``PW_CHECK_*`` can trigger circular dependencies when asserts are used from
411 low-level contexts, like in ``<span>``.
412
Wyatt Heplera59998f2021-03-19 14:35:10 -0700413**PW_ASSERT** solves all of the above problems: No risk of ODR violations, are
414constexpr safe, and have a tiny call site footprint; and there is no header
415dependency on the backend preventing circular include issues. However, there
416are **no format messages, no captured line number, no captured file, no captured
417expression, or anything other than a binary indication of failure**.
Keir Mierle854adec2020-09-03 14:07:19 -0700418
419Example
420-------
421
422.. code-block:: cpp
423
424 // This example demonstrates asserting in a header.
425
Wyatt Heplera59998f2021-03-19 14:35:10 -0700426 #include "pw_assert/assert.h"
Keir Mierle854adec2020-09-03 14:07:19 -0700427
428 class InlinedSubsystem {
429 public:
430 void DoSomething() {
431 // GOOD: No problem; PW_ASSERT is fine to inline and place in a header.
432 PW_ASSERT(IsEnabled());
433 }
434 void DoSomethingElse() {
435 // BAD: Generally avoid using PW_DCHECK() or PW_CHECK in headers. If you
436 // want rich asserts or logs, move the function into the .cc file, and
437 // then use PW_CHECK there.
438 PW_DCHECK(IsEnabled()); // DON'T DO THIS
439 }
440 };
441
Wyatt Heplera59998f2021-03-19 14:35:10 -0700442PW_ASSERT API reference
443-----------------------
Keir Mierle854adec2020-09-03 14:07:19 -0700444.. cpp:function:: PW_ASSERT(condition)
445
446 A header- and constexpr-safe version of ``PW_CHECK()``.
447
448 If the given condition is false, crash the system. Otherwise, do nothing.
449 The condition is guaranteed to be evaluated. This assert implementation is
450 guaranteed to be constexpr-safe.
451
452.. cpp:function:: PW_DASSERT(condition)
453
454 A header- and constexpr-safe version of ``PW_DCHECK()``.
455
456 Same as ``PW_ASSERT()``, except that if ``PW_ASSERT_ENABLE_DEBUG == 1``, the
457 assert is disabled and condition is not evaluated.
458
459.. attention::
460
461 Unlike the ``PW_CHECK_*()`` suite of macros, ``PW_ASSERT()`` and
462 ``PW_DASSERT()`` capture no rich information like line numbers, the file,
463 expression arguments, or the stringified expression. Use these macros **only
Alexei Frolov5a0450d2020-10-28 21:10:47 -0700464 when absolutely necessary**---in headers, constexpr contexts, or in rare cases
Keir Mierle854adec2020-09-03 14:07:19 -0700465 where the call site overhead of a full PW_CHECK must be avoided.
466
467 Use ``PW_CHECK_*()`` whenever possible.
468
Wyatt Heplera59998f2021-03-19 14:35:10 -0700469PW_ASSERT API backend
470---------------------
471The ``PW_ASSERT`` API ultimately calls the C function
472``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert``
Wyatt Hepler66064662021-05-03 09:15:40 -0700473backend. The ``pw_assert_HandleFailure()`` function must not return.
Keir Mierle854adec2020-09-03 14:07:19 -0700474
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700475.. _module-pw_assert-circular-deps:
476
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700477Avoiding circular dependencies with ``PW_ASSERT``
478-------------------------------------------------
479Because asserts are so widely used, including in low-level libraries, it is
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700480common for the ``pw_assert`` backend to cause circular dependencies. Because of
481this, assert backends may avoid declaring explicit dependencies, instead relying
482on include paths to access header files.
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700483
Wyatt Hepler61663222021-05-06 10:57:43 -0700484In GN, the ``pw_assert`` backend's full implementation with true dependencies is
485made available through the ``$dir_pw_assert:impl`` group. When
486``pw_assert_BACKEND`` is set, ``$dir_pw_assert:impl`` must be listed in the
487``pw_build_LINK_DEPS`` variable. See :ref:`module-pw_build-link-deps`.
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700488
Wyatt Hepler61663222021-05-06 10:57:43 -0700489In the ``pw_assert``, the backend's full implementation is placed in the
490``$pw_assert_BACKEND.impl`` target. ``$dir_pw_assert:impl`` depends on this
491backend target. The ``$pw_assert_BACKEND.impl`` target may be an empty group if
492the backend target can use its dependencies directly without causing circular
493dependencies.
494
495In order to break dependency cycles, the ``pw_assert_BACKEND`` target may need
496to directly provide dependencies through include paths only, rather than GN
497``public_deps``. In this case, GN header checking can be disabled with
498``check_includes = false``.
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700499
Armando Montanez179aa8e2021-03-10 11:46:35 -0800500.. _module-pw_assert-backend_api:
501
Keir Mierle854adec2020-09-03 14:07:19 -0700502-----------
503Backend API
504-----------
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800505
506The backend controls what to do in the case of an assertion failure. In the
507most basic cases, the backend could display the assertion failure on something
508like sys_io and halt in a while loop waiting for a debugger. In other cases,
509the backend could store crash details like the current thread's stack to flash.
510
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700511This facade module (``pw_assert``) does not provide a backend. See
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -0700512:ref:`module-pw_assert_basic` for a basic implementation.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800513
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700514.. attention::
515
516 The facade macros (``PW_CRASH`` and related) are expected to behave like they
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700517 have the ``[[noreturn]]`` attribute set. This implies that the backend handler
518 functions, ``PW_HANDLE_*`` defined by the backend, must not return.
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700519
520 In other words, the device must reboot.
521
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700522The backend must provide the header
523
524``pw_assert_backend/backend.h``
525
526and that header must define the following macros:
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800527
528.. cpp:function:: PW_HANDLE_CRASH(message, ...)
529
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700530 Trigger a system crash or halt, and if possible, deliver the specified
531 message and arguments to the user or developer.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800532
533.. cpp:function:: PW_HANDLE_ASSERT_FAILURE(condition_str, message, ...)
534
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700535 Trigger a system crash or halt, and if possible, deliver the condition string
536 (indicating what expression was false) and the message with format arguments,
537 to the user or developer.
538
539 This macro is invoked from the ``PW_CHECK`` facade macro if condition is
540 false.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800541
542.. cpp:function:: PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \
543 a_str, a_val, op_str, b_str, b_val, type_fmt, message, ...)
544
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700545 Trigger a system crash or halt for a failed binary comparison assert (e.g.
546 any of the ``PW_CHECK_<type>_<op>`` macros). The handler should combine the
547 assert components into a useful message for the user; though in some cases
548 this may not be possible.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800549
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700550 Consider the following example:
551
552 .. code-block:: cpp
553
554 int temp = 16;
555 int max_temp = 15;
556 PW_CHECK_INT_LE(temp, MAX_TEMP, "Got too hot; state: %s", GetSystemState());
557
558 In this block, the assert will trigger, which will cause the facade to invoke
559 the handler macro. Below is the meaning of the arguments, referencing to the
560 example:
561
562 - ``a_str`` - Stringified first operand. In the example: ``"temp"``.
563 - ``a_val`` - The value of the first operand. In the example: ``16``.
564 - ``op_str`` - The string version of the operator. In the example: "<=".
565 - ``b_str`` - Stringified second operand. In the example: ``"max_temp"``.
566 - ``b_val`` - The value of the second operand. In the example: ``15``.
567 - ``type_fmt`` - The format code for the type. In the example: ``"%d"``.
568 - ``message, ...`` - A formatted message to go with the assert. In the
569 example: ``"Got too hot; state: %s", "ON_FIRE"``.
570
571 .. tip::
572
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -0700573 See :ref:`module-pw_assert_basic` for one way to combine these arguments
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700574 into a meaningful error message.
575
Wyatt Heplera59998f2021-03-19 14:35:10 -0700576Additionally, the backend must provide a link-time function for the
577``PW_ASSERT`` assert handler. This does not need to appear in the backend
578header, but instead is in a ``.cc`` file.
Keir Mierle854adec2020-09-03 14:07:19 -0700579
580.. cpp:function:: pw_assert_HandleFailure()
581
582 Handle a low-level crash. This crash entry happens through
Wyatt Heplera59998f2021-03-19 14:35:10 -0700583 ``pw_assert/assert.h``. In this crash handler, there is no access to line,
Keir Mierle854adec2020-09-03 14:07:19 -0700584 file, expression, or other rich assert information. Backends should do
585 something reasonable in this case; typically, capturing the stack is useful.
586
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700587Backend build targets
588---------------------
Wyatt Hepler61663222021-05-06 10:57:43 -0700589In GN, the backend must provide a ``pw_assert.impl`` build target in the same
590directory as the backend target. If the main backend target's dependencies would
591cause dependency cycles, the actual backend implementation with its full
592dependencies is placed in the ``pw_assert.impl`` target. If this is not
593necessary, ``pw_assert.impl`` can be an empty group. Circular dependencies are a
594common problem with ``pw_assert`` because it is so widely used. See
595:ref:`module-pw_assert-circular-deps`.
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700596
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700597--------------------------
598Frequently asked questions
599--------------------------
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700600
Keir Mierle3f356722020-07-31 00:43:43 -0700601When should DCHECK_* be used instead of CHECK_* and vice versa?
602---------------------------------------------------------------
603There is no hard and fast rule for when to use one or the other.
604
605In theory, ``DCHECK_*`` macros should never be used and all the asserts should
606remain active in production. In practice, **assert statements come at a binary
607size and runtime cost**, even when using extensions like a tokenized assert
608backend that strips the stringified assert expression from the binary. Each
609assert is **at least a branch with a function call**; depending on the assert
610backend, that function call may take several arguments (like the message, the
611file line number, the module, etc). These function calls can take 10-20 bytes
612or more of ROM each. Thus, there is a balance to be struct between ``DCHECK_*``
613and ``CHECK_*``.
614
615Pigweed uses these conventions to decide between ``CHECK_*`` and ``DCHECK_*``:
616
617- **Prefer to use CHECK_* at public API boundaries** of modules, where an
618 invalid value is a clear programmer bug. In certain cases use ``DCHECK_*`` to
619 keep binary size small when in production; for example, in modules with a
620 large public API surface, or modules with many inlined functions in headers.
621- **Avoid using CHECK_* macros in headers.** It is still OK to use ``CHECK_*``
622 macros in headers, but carefully consider the cost, since inlined use of the
623 ``CHECK_*`` macros in headers will expand to the full assert cost for every
624 translation unit that includes the header and calls the function with the
625 ``CHECK_*`` instance. ``DCHECK_*`` macros are are better, but even they come
626 at a cost, since it is preferable to be able to compile a binary in debug
627 mode for as long as possible on the road to production.
628- **Prefer to use DCHECK_* variants for internal asserts** that attempt to
629 catch module-author level programming errors. For example, use DCHECKs to
630 verify internal function preconditions, or other invariants that should
631 always be true but will likely never fire in production. In some cases using
632 ``CHECK_*`` macros for internal consistency checking can make sense, if the
633 runtime cost is low and there are only a couple of instances.
634
635.. tip::
636
Keir Mierle481d8292020-07-31 01:10:05 -0700637 **Do not return error status codes for obvious API misuse**
Keir Mierle3f356722020-07-31 00:43:43 -0700638
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700639 Returning an error code may **mask the earliest sign of a bug** because
640 notifying the developer of the problem depends on correct propagation of the
641 error to upper levels of the system. Instead, prefer to use the ``CHECK_*``
642 or ``DCHECK_*`` macros to ensure a prompt termination and warning to the
643 developer.
Keir Mierle3f356722020-07-31 00:43:43 -0700644
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700645 **Error status codes should be reserved for system misbehaviour or expected
646 exceptional cases**, like a sensor is not yet ready, or a storage subsystem
647 is full when writing. Doing ``CHECK_*`` assertions in those cases would be a
Keir Mierle3f356722020-07-31 00:43:43 -0700648 mistake; so use error codes in those cases instead.
649
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700650How should objects be asserted against or compared?
651---------------------------------------------------
Shiva Rajagopal9e516562021-05-11 17:04:15 -0700652Unfortunately, there is no native mechanism for this, and instead the way to
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700653assert object states or comparisons is with the normal ``PW_CHECK_*`` macros
654that operate on booleans, ints, and floats.
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700655
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700656This is due to the requirement of supporting C and also tokenization. It may be
Shiva Rajagopal9e516562021-05-11 17:04:15 -0700657possible support rich object comparisons by defining a convention for
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700658stringifying objects; however, this hasn't been added yet. Additionally, such a
659mechanism would not work well with tokenization. In particular, it would
660require runtime stringifying arguments and rendering them with ``%s``, which
661leads to binary bloat even with tokenization. So it is likely that a rich
662object assert API won't be added.
663
664Why was the assert facade designed this way?
665--------------------------------------------
666The Pigweed assert API was designed taking into account the needs of several
667past projects the team members were involved with. Based on those experiences,
668the following were key requirements for the API:
669
6701. **C compatibility** - Since asserts are typically invoked from arbitrary
671 contexts, including from vendor or third party code, the assert system must
672 have a C-compatible API. Some API functions working only in C++ is
673 acceptable, as long as the key functions work in C.
6742. **Capturing both expressions and values** - Since asserts can trigger in
675 ways that are not repeatable, it is important to capture rich diagnostic
676 information to help identifying the root cause of the fault. For asserts,
677 this means including the failing expression text, and optionally also
678 capturing failing expression values. For example, instead of capturing an
679 error with the expression (``x < y``), capturing an error with the
680 expression and values(``x < y, with x = 10, y = 0``).
6813. **Tokenization compatible** - It's important that the assert expressions
682 support tokenization; both the expression itself (e.g. ``a < b``) and the
683 message attached to the expression. For example: ``PW_CHECK(ItWorks(), "Ruh
684 roh: %d", some_int)``.
6854. **Customizable assert handling** - Most products need to support custom
686 handling of asserts. In some cases, an assert might trigger printing out
687 details to a UART; in other cases, it might trigger saving a log entry to
688 flash. The assert system must support this customization.
689
690The combination of #1, #2, and #3 led to the structure of the API. In
691particular, the need to support tokenized asserts and the need to support
692capturing values led to the choice of having ``PW_CHECK_INT_LE(a, b)`` instead
693of ``PW_CHECK(a <= b)``. Needing to support tokenization is what drove the
694facade & backend arrangement, since the backend must provide the raw macros for
695asserting in that case, rather than terminating at a C-style API.
696
697Why isn't there a ``PW_CHECK_LE``? Why is the type (e.g. ``INT``) needed?
698-------------------------------------------------------------------------
699The problem with asserts like ``PW_CHECK_LE(a, b)`` instead of
700``PW_CHECK_INT_LE(a, b)`` or ``PW_CHECK_FLOAT_EXACT_LE(a, b)`` is that to
701capture the arguments with the tokenizer, we need to know the types. Using the
702preprocessor, it is impossible to dispatch based on the types of ``a`` and
703``b``, so unfortunately having a separate macro for each of the types commonly
704asserted on is necessary.
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700705
706-------------
707Compatibility
708-------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700709The facade is compatible with both C and C++.
710
711----------------
712Roadmap & Status
713----------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700714The Pigweed assert subsystem consiststs of several modules that work in
Keir Mierle854adec2020-09-03 14:07:19 -0700715coordination. This module is the facade (API), then a number of backends are
716available to handle assert failures. Products can also define their own
717backends. In some cases, the backends will have backends (like
718``pw_log_tokenized``).
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700719
Keir Mierle854adec2020-09-03 14:07:19 -0700720Below is a brief summary of what modules are ready for use:
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700721
Keir Mierle854adec2020-09-03 14:07:19 -0700722Available assert backends
723-------------------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700724- ``pw_assert`` - **Stable** - The assert facade (this module). This module is
725 stable, and in production use. The documentation is comprehensive and covers
726 the functionality. There are (a) tests for the facade macro processing logic,
727 using a fake assert backend; and (b) compile tests to verify that the
728 selected backend compiles with all supported assert constructions and types.
729- ``pw_assert_basic`` - **Stable** - The assert basic module is a simple assert
730 handler that displays the failed assert line and the values of captured
731 arguments. Output is directed to ``pw_sys_io``. This module is a great
732 ready-to-roll module when bringing up a system, but is likely not the best
733 choice for production.
Keir Mierle854adec2020-09-03 14:07:19 -0700734- ``pw_assert_log`` - **Stable** - This assert backend redirects to logging,
735 but with a logging flag set that indicates an assert failure. This is our
736 advised approach to get **tokenized asserts**--by using tokenized logging,
737 then using the ``pw_assert_log`` backend.
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700738
Keir Mierle854adec2020-09-03 14:07:19 -0700739Note: If one desires a null assert module (where asserts are removed), use
740``pw_assert_log`` in combination with ``pw_log_null``. This will direct asserts
741to logs, then the logs are removed due to the null backend.
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700742
743Missing functionality
744---------------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700745- **Stack traces** - Pigweed doesn't have a reliable stack walker, which makes
746 displaying a stack trace on crash harder. We plan to add this eventually.
747- **Snapshot integration** - Pigweed doesn't yet have a rich system state
748 capture system that can capture state like number of tasks, available memory,
749 and so on. Snapshot facilities are the obvious ones to run inside an assert
750 handler. It'll happen someday.