• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _module-pw_assert:
2
3=========
4pw_assert
5=========
6
7--------
8Overview
9--------
10Pigweed'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.
13
14The assert API facilitates flexible crash handling through Pigweed's facade
15mechanism. The API is designed to enable features like:
16
17- 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
20
21The ``pw_assert`` API provides three classes of macros:
22
23- **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.
28- **PW_ASSERT(condition)** - Header- and constexpr-safe assert.
29
30.. tip::
31
32  All of the ``CHECK`` macros optionally support a message with additional
33  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
40  To ensure compatibility with :ref:`module-pw_assert_log` and
41  :ref:`module-pw_log_tokenized`, the message must be a string literal.
42
43Example
44=======
45
46.. code-block:: cpp
47
48  #include "pw_assert/check.h"
49
50  int main() {
51    bool sensor_running = StartSensor(&msg);
52    PW_CHECK(sensor_running, "Sensor failed to start; code: %s", msg);
53
54    int temperature_c = ReadSensorCelcius();
55    PW_CHECK_INT_LE(temperature_c, 100,
56                    "System is way out of heat spec; state=%s",
57                    ReadSensorStateString());
58  }
59
60.. tip::
61
62  All macros have both a ``CHECK`` and ``DCHECK`` variant. The ``CHECK``
63  variant is always enabled, even in production. Generally, we advise making
64  most asserts ``CHECK`` rather than ``DCHECK``, unless there is a critical
65  performance or code size reason to use ``DCHECK``.
66
67  .. code-block:: cpp
68
69    // This assert is always enabled, even in production.
70    PW_CHECK_INT_LE(ItemCount(), 100);
71
72    // This assert is enabled based on ``PW_ASSERT_ENABLE_DEBUG``.
73    // The functions ItemCount() and GetStateStr() are never called.
74    PW_DCHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr());
75
76.. tip::
77
78  Use ``PW_ASSERT`` from ``pw_assert/assert.h`` for asserts in headers or
79  asserting in ``constexpr`` contexts.
80
81Structure of Assert Modules
82===========================
83The module is split into two components:
84
851. The **facade** (this module) which is only a macro interface layer, and
86   performs the actual checks for the conditions.
872. The **backend**, provided elsewhere, that handles the consequences of an
88   assert failing. Example backends include ``pw_assert_basic``, which prints a
89   useful message and either quits the application (on host) or hangs in a
90   while loop (on device). In the future, there will be a tokenized assert
91   backend. This is also where application or product specific crash handling
92   would go.
93
94.. mermaid::
95
96  graph LR
97    facade --> backend
98
99See the Backend API section below for more details.
100
101----------
102Facade API
103----------
104The below functions describe the assert API functions that applications should
105invoke to assert. These macros are found in the ``pw_assert/check.h`` header.
106
107.. cpp:function:: PW_CRASH(format, ...)
108
109  Trigger a crash with a message. Replaces LOG_FATAL() in other systems. Can
110  include a message with format arguments; for example:
111
112  .. code-block:: cpp
113
114    PW_CRASH("Unexpected: frobnitz in state: %s", frobnitz_state);
115
116  Note: ``PW_CRASH`` is the equivalent of ``LOG_FATAL`` in other systems, where
117  a device crash is triggered with a message. In Pigweed, logging and
118  crashing/asserting are separated. There is a ``LOG_CRITICAL`` level in the
119  logging module, but it does not have side effects; for ``LOG_FATAL``, instead
120  use this macro (``PW_CRASH``).
121
122.. cpp:function:: PW_CHECK(condition)
123.. cpp:function:: PW_CHECK(condition, format, ...)
124.. cpp:function:: PW_DCHECK(condition)
125.. cpp:function:: PW_DCHECK(condition, format, ...)
126
127  Assert that a condition is true, optionally including a message with
128  arguments to report if the codition is false.
129
130  The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
131  otherwise, the entire statement is removed (and the expression not evaluated).
132
133  Example:
134
135  .. code-block:: cpp
136
137    PW_CHECK(StartTurbines());
138    PW_CHECK(StartWarpDrive(), "Oddly warp drive couldn't start; ruh-roh!");
139    PW_CHECK(RunSelfTest(), "Failure in self test; try %d", TestAttempts());
140
141  .. attention::
142
143    Don't use use ``PW_CHECK`` for binary comparisons or status checks!
144
145    Instead, use the ``PW_CHECK_<TYPE>_<OP>`` macros. These macros enable
146    capturing the value of the operands, and also tokenizing them if using a
147    tokenizing assert backend. For example, if ``x`` and ``b`` are integers,
148    use instead ``PW_CHECK_INT_LT(x, b)``.
149
150    Additionally, use ``PW_CHECK_OK(status)`` when checking for an OK status,
151    since it enables showing a human-readable status string rather than an
152    integer (e.g. ``status == RESOURCE_EXHAUSTED`` instead of ``status == 5``.
153
154    +------------------------------------+-------------------------------------+
155    | **Do NOT do this**                 | **Do this instead**                 |
156    +------------------------------------+-------------------------------------+
157    | ``PW_CHECK(a_int < b_int)``        | ``PW_CHECK_INT_LT(a_int, b_int)``   |
158    +------------------------------------+-------------------------------------+
159    | ``PW_CHECK(a_ptr <= b_ptr)``       | ``PW_CHECK_PTR_LE(a_ptr, b_ptr)``   |
160    +------------------------------------+-------------------------------------+
161    | ``PW_CHECK(Temp() <= 10.0)``       | ``PW_CHECK_FLOAT_EXACT_LE(``        |
162    |                                    | ``    Temp(), 10.0)``               |
163    +------------------------------------+-------------------------------------+
164    | ``PW_CHECK(Foo() == OkStatus())``  | ``PW_CHECK_OK(Foo())``              |
165    +------------------------------------+-------------------------------------+
166
167.. cpp:function:: PW_CHECK_NOTNULL(ptr)
168.. cpp:function:: PW_CHECK_NOTNULL(ptr, format, ...)
169.. cpp:function:: PW_DCHECK_NOTNULL(ptr)
170.. cpp:function:: PW_DCHECK_NOTNULL(ptr, format, ...)
171
172  Assert that the given pointer is not ``NULL``, optionally including a message
173  with arguments to report if the pointer is ``NULL``.
174
175  The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
176  otherwise, the entire statement is removed (and the expression not evaluated).
177
178  .. code-block:: cpp
179
180    Foo* foo = GetTheFoo()
181    PW_CHECK_NOTNULL(foo);
182
183    Bar* bar = GetSomeBar();
184    PW_CHECK_NOTNULL(bar, "Weirdly got NULL bar; state: %d", MyState());
185
186.. cpp:function:: PW_CHECK_TYPE_OP(a, b)
187.. cpp:function:: PW_CHECK_TYPE_OP(a, b, format, ...)
188.. cpp:function:: PW_DCHECK_TYPE_OP(a, b)
189.. cpp:function:: PW_DCHECK_TYPE_OP(a, b, format, ...)
190
191  Asserts that ``a OP b`` is true, where ``a`` and ``b`` are converted to
192  ``TYPE``; with ``OP`` and ``TYPE`` described below.
193
194  If present, the optional format message is reported on failure. Depending on
195  the backend, values of ``a`` and ``b`` will also be reported.
196
197  The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
198  otherwise, the entire statement is removed (and the expression not evaluated).
199
200  Example, with no message:
201
202  .. code-block:: cpp
203
204    PW_CHECK_INT_LE(CurrentTemperature(), 100);
205    PW_CHECK_INT_LE(ItemCount(), 100);
206
207  Example, with an included message and arguments:
208
209  .. code-block:: cpp
210
211    PW_CHECK_FLOAT_EXACT_GE(BatteryVoltage(), 3.2,
212                            "System state=%s", SysState());
213
214  Below is the full list of binary comparison assert macros, along with the
215  type specifier. The specifier is irrelevant to application authors but is
216  needed for backend implementers.
217
218  +-------------------------+--------------+-----------+-----------------------+
219  | Macro                   | a, b type    | condition | a, b format specifier |
220  +-------------------------+--------------+-----------+-----------------------+
221  | PW_CHECK_INT_LE         | int          | a <= b    | %d                    |
222  +-------------------------+--------------+-----------+-----------------------+
223  | PW_CHECK_INT_LT         | int          | a <  b    | %d                    |
224  +-------------------------+--------------+-----------+-----------------------+
225  | PW_CHECK_INT_GE         | int          | a >= b    | %d                    |
226  +-------------------------+--------------+-----------+-----------------------+
227  | PW_CHECK_INT_GT         | int          | a >  b    | %d                    |
228  +-------------------------+--------------+-----------+-----------------------+
229  | PW_CHECK_INT_EQ         | int          | a == b    | %d                    |
230  +-------------------------+--------------+-----------+-----------------------+
231  | PW_CHECK_INT_NE         | int          | a != b    | %d                    |
232  +-------------------------+--------------+-----------+-----------------------+
233  | PW_CHECK_UINT_LE        | unsigned int | a <= b    | %u                    |
234  +-------------------------+--------------+-----------+-----------------------+
235  | PW_CHECK_UINT_LT        | unsigned int | a <  b    | %u                    |
236  +-------------------------+--------------+-----------+-----------------------+
237  | PW_CHECK_UINT_GE        | unsigned int | a >= b    | %u                    |
238  +-------------------------+--------------+-----------+-----------------------+
239  | PW_CHECK_UINT_GT        | unsigned int | a >  b    | %u                    |
240  +-------------------------+--------------+-----------+-----------------------+
241  | PW_CHECK_UINT_EQ        | unsigned int | a == b    | %u                    |
242  +-------------------------+--------------+-----------+-----------------------+
243  | PW_CHECK_UINT_NE        | unsigned int | a != b    | %u                    |
244  +-------------------------+--------------+-----------+-----------------------+
245  | PW_CHECK_PTR_LE         | void*        | a <= b    | %p                    |
246  +-------------------------+--------------+-----------+-----------------------+
247  | PW_CHECK_PTR_LT         | void*        | a <  b    | %p                    |
248  +-------------------------+--------------+-----------+-----------------------+
249  | PW_CHECK_PTR_GE         | void*        | a >= b    | %p                    |
250  +-------------------------+--------------+-----------+-----------------------+
251  | PW_CHECK_PTR_GT         | void*        | a >  b    | %p                    |
252  +-------------------------+--------------+-----------+-----------------------+
253  | PW_CHECK_PTR_EQ         | void*        | a == b    | %p                    |
254  +-------------------------+--------------+-----------+-----------------------+
255  | PW_CHECK_PTR_NE         | void*        | a != b    | %p                    |
256  +-------------------------+--------------+-----------+-----------------------+
257  | PW_CHECK_FLOAT_EXACT_LE | float        | a <= b    | %f                    |
258  +-------------------------+--------------+-----------+-----------------------+
259  | PW_CHECK_FLOAT_EXACT_LT | float        | a <  b    | %f                    |
260  +-------------------------+--------------+-----------+-----------------------+
261  | PW_CHECK_FLOAT_EXACT_GE | float        | a >= b    | %f                    |
262  +-------------------------+--------------+-----------+-----------------------+
263  | PW_CHECK_FLOAT_EXACT_GT | float        | a >  b    | %f                    |
264  +-------------------------+--------------+-----------+-----------------------+
265  | PW_CHECK_FLOAT_EXACT_EQ | float        | a == b    | %f                    |
266  +-------------------------+--------------+-----------+-----------------------+
267  | PW_CHECK_FLOAT_EXACT_NE | float        | a != b    | %f                    |
268  +-------------------------+--------------+-----------+-----------------------+
269
270  The above ``CHECK_*_*()`` are also available in DCHECK variants, which will
271  only evaluate their arguments and trigger if the ``PW_ASSERT_ENABLE_DEBUG``
272  macro is enabled.
273
274  +--------------------------+--------------+-----------+----------------------+
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 ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
348  otherwise, the 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());
362
363.. 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
368  Assert that ``status`` evaluates to ``pw::OkStatus()`` (in C++) or
369  ``PW_STATUS_OK`` (in C). Optionally include a message with arguments to
370  report.
371
372  The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is defined;
373  otherwise, the 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
389    Using ``PW_CHECK_OK(status)`` instead of ``PW_CHECK(status == OkStatus())``
390    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
394.. _module-pw_assert-assert-api:
395
396----------
397Assert API
398----------
399The normal ``PW_CHECK_*`` and ``PW_DCHECK_*`` family of macros are intended to
400provide rich debug information, like the file, line number, value of operands
401in boolean comparisons, and more. However, this comes at a cost: these macros
402depend directly on the backend headers, and may perform complicated call-site
403transformations like tokenization.
404
405There are several issues with the normal ``PW_CHECK_*`` suite of macros:
406
4071. ``PW_CHECK_*`` in headers can cause ODR violations in the case of tokenized
408   asserts, due to differing module choices.
4092. ``PW_CHECK_*`` is not constexpr-safe.
4103. ``PW_CHECK_*`` can cause code bloat with some backends; this is the tradeoff
411   to get rich assert information.
4124. ``PW_CHECK_*`` can trigger circular dependencies when asserts are used from
413   low-level contexts, like in ``<span>``.
414
415**PW_ASSERT** solves all of the above problems: No risk of ODR violations, are
416constexpr safe, and have a tiny call site footprint; and there is no header
417dependency on the backend preventing circular include issues.  However, there
418are **no format messages, no captured line number, no captured file, no captured
419expression, or anything other than a binary indication of failure**.
420
421Example
422=======
423
424.. code-block:: cpp
425
426  // This example demonstrates asserting in a header.
427
428  #include "pw_assert/assert.h"
429
430  class InlinedSubsystem {
431   public:
432    void DoSomething() {
433      // GOOD: No problem; PW_ASSERT is fine to inline and place in a header.
434      PW_ASSERT(IsEnabled());
435    }
436    void DoSomethingElse() {
437      // BAD: Generally avoid using PW_DCHECK() or PW_CHECK in headers. If you
438      // want rich asserts or logs, move the function into the .cc file, and
439      // then use PW_CHECK there.
440      PW_DCHECK(IsEnabled());  // DON'T DO THIS
441    }
442  };
443
444PW_ASSERT API Reference
445=======================
446.. cpp:function:: PW_ASSERT(condition)
447
448  A header- and constexpr-safe version of ``PW_CHECK()``.
449
450  If the given condition is false, crash the system. Otherwise, do nothing.
451  The condition is guaranteed to be evaluated. This assert implementation is
452  guaranteed to be constexpr-safe.
453
454.. cpp:function:: PW_DASSERT(condition)
455
456  A header- and constexpr-safe version of ``PW_DCHECK()``.
457
458  Same as ``PW_ASSERT()``, except that if ``PW_ASSERT_ENABLE_DEBUG == 0``, the
459  assert is disabled and condition is not evaluated.
460
461.. attention::
462
463  Unlike the ``PW_CHECK_*()`` suite of macros, ``PW_ASSERT()`` and
464  ``PW_DASSERT()`` capture no rich information like line numbers, the file,
465  expression arguments, or the stringified expression. Use these macros **only
466  when absolutely necessary**---in headers, constexpr contexts, or in rare cases
467  where the call site overhead of a full PW_CHECK must be avoided.
468
469  Use ``PW_CHECK_*()`` whenever possible.
470
471PW_ASSERT API Backend
472=====================
473The ``PW_ASSERT`` API ultimately calls the C function
474``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert``
475backend. The ``pw_assert_HandleFailure()`` function must not return.
476
477.. _module-pw_assert-circular-deps:
478
479Avoiding Circular Dependencies With ``PW_ASSERT``
480=================================================
481Because asserts are so widely used, including in low-level libraries, it is
482common for the ``pw_assert`` backend to cause circular dependencies. Because of
483this, assert backends may avoid declaring explicit dependencies, instead relying
484on include paths to access header files.
485
486In GN, the ``pw_assert`` backend's full implementation with true dependencies is
487made available through the ``$dir_pw_assert:impl`` group. When
488``pw_assert_BACKEND`` is set, ``$dir_pw_assert:impl`` must be listed in the
489``pw_build_LINK_DEPS`` variable. See :ref:`module-pw_build-link-deps`.
490
491In the ``pw_assert``, the backend's full implementation is placed in the
492``$pw_assert_BACKEND.impl`` target. ``$dir_pw_assert:impl`` depends on this
493backend target. The ``$pw_assert_BACKEND.impl`` target may be an empty group if
494the backend target can use its dependencies directly without causing circular
495dependencies.
496
497In order to break dependency cycles, the ``pw_assert_BACKEND`` target may need
498to directly provide dependencies through include paths only, rather than GN
499``public_deps``. In this case, GN header checking can be disabled with
500``check_includes = false``.
501
502.. _module-pw_assert-backend_api:
503
504-----------
505Backend API
506-----------
507The backend controls what to do in the case of an assertion failure. In the
508most basic cases, the backend could display the assertion failure on something
509like sys_io and halt in a while loop waiting for a debugger. In other cases,
510the backend could store crash details like the current thread's stack to flash.
511
512This facade module (``pw_assert``) does not provide a backend. See
513:ref:`module-pw_assert_basic` for a basic implementation.
514
515.. attention::
516
517  The facade macros (``PW_CRASH`` and related) are expected to behave like they
518  have the ``[[noreturn]]`` attribute set. This implies that the backend handler
519  functions, ``PW_HANDLE_*`` defined by the backend, must not return.
520
521  In other words, the device must reboot.
522
523The backend must provide the header
524
525``pw_assert_backend/backend.h``
526
527and that header must define the following macros:
528
529.. cpp:function:: PW_HANDLE_CRASH(message, ...)
530
531  Trigger a system crash or halt, and if possible, deliver the specified
532  message and arguments to the user or developer.
533
534.. cpp:function:: PW_HANDLE_ASSERT_FAILURE(condition_str, message, ...)
535
536  Trigger a system crash or halt, and if possible, deliver the condition string
537  (indicating what expression was false) and the message with format arguments,
538  to the user or developer.
539
540  This macro is invoked from the ``PW_CHECK`` facade macro if condition is
541  false.
542
543.. cpp:function:: PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \
544    a_str, a_val, op_str, b_str, b_val, type_fmt, message, ...)
545
546  Trigger a system crash or halt for a failed binary comparison assert (e.g.
547  any of the ``PW_CHECK_<type>_<op>`` macros). The handler should combine the
548  assert components into a useful message for the user; though in some cases
549  this may not be possible.
550
551  Consider the following example:
552
553  .. code-block:: cpp
554
555    int temp = 16;
556    int max_temp = 15;
557    PW_CHECK_INT_LE(temp, MAX_TEMP, "Got too hot; state: %s", GetSystemState());
558
559  In this block, the assert will trigger, which will cause the facade to invoke
560  the handler macro. Below is the meaning of the arguments, referencing to the
561  example:
562
563  - ``a_str`` - Stringified first operand. In the example: ``"temp"``.
564  - ``a_val`` - The value of the first operand. In the example: ``16``.
565  - ``op_str`` - The string version of the operator. In the example: "<=".
566  - ``b_str`` - Stringified second operand. In the example: ``"max_temp"``.
567  - ``b_val`` - The value of the second operand. In the example: ``15``.
568  - ``type_fmt`` - The format code for the type. In the example: ``"%d"``.
569  - ``message, ...`` - A formatted message to go with the assert. In the
570    example: ``"Got too hot; state: %s", "ON_FIRE"``.
571
572  .. tip::
573
574    See :ref:`module-pw_assert_basic` for one way to combine these arguments
575    into a meaningful error message.
576
577Additionally, the backend must provide a link-time function for the
578``PW_ASSERT`` assert handler. This does not need to appear in the backend
579header, but instead is in a ``.cc`` file.
580
581.. cpp:function:: pw_assert_HandleFailure()
582
583  Handle a low-level crash. This crash entry happens through
584  ``pw_assert/assert.h``. In this crash handler, there is no access to line,
585  file, expression, or other rich assert information. Backends should do
586  something reasonable in this case; typically, capturing the stack is useful.
587
588Backend Build Targets
589=====================
590In GN, the backend must provide a ``pw_assert.impl`` build target in the same
591directory as the backend target. If the main backend target's dependencies would
592cause dependency cycles, the actual backend implementation with its full
593dependencies is placed in the ``pw_assert.impl`` target. If this is not
594necessary, ``pw_assert.impl`` can be an empty group. Circular dependencies are a
595common problem with ``pw_assert`` because it is so widely used. See
596:ref:`module-pw_assert-circular-deps`.
597
598Macro-based PW_ASSERT()/PW_DASSERT() backend
599============================================
600The pw_assert API is being re-assessed to provide more helpful information in
601contexts where ``PW_CHECK_*()`` macros cannot be used. A first step towards this
602is providing a macro-based backend API for the ``PW_ASSERT()`` and
603``PW_DASSERT()`` macros.
604
605.. warning::
606  This part of ``pw_assert``'s API is transitional, and any project-specific
607  reliance on any of the API mentioned here will likely experience breakages.
608  In particular, ``PW_ASSERT_HANDLE_FAILURE`` and ``PW_HANDLE_ASSERT_FAILURE``
609  are extremely confusingly similar and are NOT interchangeable.
610
611A macro-based backend for the ``PW_ASSERT()`` macros must provide the following
612macro in a header at ``pw_assert_backend/assert_lite_backend.h``.
613
614.. cpp:function:: PW_ASSERT_HANDLE_FAILURE(expression)
615
616  Handle a low-level crash. This crash entry happens through
617  ``pw_assert/assert.h``. Backends must ensure their implementation is safe for
618  usage in headers, constexpr contexts, and templates. This macro should expand
619  to an expression that does not return.
620
621Similar to the ``PW_CHECK_*()`` facade, the header backend that provides an
622expansion for the ``PW_ASSERT_HANDLE_FAILURE()`` macro can be controlled in the
623GN build using the ``pw_assert_LITE_BACKEND`` build argument. In addition to
624the header-based target at ``${pw_assert_LITE_BACKEND}``, a source set at
625``${pw_assert_LITE_BACKEND}.impl`` is also required as a way to reduce the
626impact of :ref:`circular dependencies <module-pw_assert-circular-deps>`.
627
628--------------------------
629Frequently Asked Questions
630--------------------------
631
632When should DCHECK_* be used instead of CHECK_* and vice versa?
633===============================================================
634There is no hard and fast rule for when to use one or the other.
635
636In theory, ``DCHECK_*`` macros should never be used and all the asserts should
637remain active in production. In practice, **assert statements come at a binary
638size and runtime cost**, even when using extensions like a tokenized assert
639backend that strips the stringified assert expression from the binary. Each
640assert is **at least a branch with a function call**; depending on the assert
641backend, that function call may take several arguments (like the message, the
642file line number, the module, etc). These function calls can take 10-20 bytes
643or more of ROM each. Thus, there is a balance to be struct between ``DCHECK_*``
644and ``CHECK_*``.
645
646Pigweed uses these conventions to decide between ``CHECK_*`` and ``DCHECK_*``:
647
648- **Prefer to use CHECK_* at public API boundaries** of modules, where an
649  invalid value is a clear programmer bug. In certain cases use ``DCHECK_*`` to
650  keep binary size small when in production; for example, in modules with a
651  large public API surface, or modules with many inlined functions in headers.
652- **Avoid using CHECK_* macros in headers.** It is still OK to use ``CHECK_*``
653  macros in headers, but carefully consider the cost, since inlined use of the
654  ``CHECK_*`` macros in headers will expand to the full assert cost for every
655  translation unit that includes the header and calls the function with the
656  ``CHECK_*`` instance. ``DCHECK_*`` macros are are better, but even they come
657  at a cost, since it is preferable to be able to compile a binary in debug
658  mode for as long as possible on the road to production.
659- **Prefer to use DCHECK_* variants for internal asserts** that attempt to
660  catch module-author level programming errors. For example, use DCHECKs to
661  verify internal function preconditions, or other invariants that should
662  always be true but will likely never fire in production. In some cases using
663  ``CHECK_*`` macros for internal consistency checking can make sense, if the
664  runtime cost is low and there are only a couple of instances.
665
666.. tip::
667
668  **Do not return error status codes for obvious API misuse**
669
670  Returning an error code may **mask the earliest sign of a bug** because
671  notifying the developer of the problem depends on correct propagation of the
672  error to upper levels of the system. Instead, prefer to use the ``CHECK_*``
673  or ``DCHECK_*`` macros to ensure a prompt termination and warning to the
674  developer.
675
676  **Error status codes should be reserved for system misbehaviour or expected
677  exceptional cases**, like a sensor is not yet ready, or a storage subsystem
678  is full when writing. Doing ``CHECK_*`` assertions in those cases would be a
679  mistake; so use error codes in those cases instead.
680
681How should objects be asserted against or compared?
682===================================================
683Unfortunately, there is no native mechanism for this, and instead the way to
684assert object states or comparisons is with the normal ``PW_CHECK_*`` macros
685that operate on booleans, ints, and floats.
686
687This is due to the requirement of supporting C and also tokenization. It may be
688possible support rich object comparisons by defining a convention for
689stringifying objects; however, this hasn't been added yet. Additionally, such a
690mechanism would not work well with tokenization. In particular, it would
691require runtime stringifying arguments and rendering them with ``%s``, which
692leads to binary bloat even with tokenization. So it is likely that a rich
693object assert API won't be added.
694
695Why was the assert facade designed this way?
696============================================
697The Pigweed assert API was designed taking into account the needs of several
698past projects the team members were involved with. Based on those experiences,
699the following were key requirements for the API:
700
7011. **C compatibility** - Since asserts are typically invoked from arbitrary
702   contexts, including from vendor or third party code, the assert system must
703   have a C-compatible API. Some API functions working only in C++ is
704   acceptable, as long as the key functions work in C.
7052. **Capturing both expressions and values** - Since asserts can trigger in
706   ways that are not repeatable, it is important to capture rich diagnostic
707   information to help identifying the root cause of the fault. For asserts,
708   this means including the failing expression text, and optionally also
709   capturing failing expression values. For example, instead of capturing an
710   error with the expression (``x < y``), capturing an error with the
711   expression and values(``x < y, with x = 10, y = 0``).
7123. **Tokenization compatible** - It's important that the assert expressions
713   support tokenization; both the expression itself (e.g. ``a < b``) and the
714   message attached to the expression. For example: ``PW_CHECK(ItWorks(), "Ruh
715   roh: %d", some_int)``.
7164. **Customizable assert handling** - Most products need to support custom
717   handling of asserts. In some cases, an assert might trigger printing out
718   details to a UART; in other cases, it might trigger saving a log entry to
719   flash. The assert system must support this customization.
720
721The combination of #1, #2, and #3 led to the structure of the API. In
722particular, the need to support tokenized asserts and the need to support
723capturing values led to the choice of having ``PW_CHECK_INT_LE(a, b)`` instead
724of ``PW_CHECK(a <= b)``. Needing to support tokenization is what drove the
725facade & backend arrangement, since the backend must provide the raw macros for
726asserting in that case, rather than terminating at a C-style API.
727
728Why isn't there a ``PW_CHECK_LE``? Why is the type (e.g. ``INT``) needed?
729=========================================================================
730The problem with asserts like ``PW_CHECK_LE(a, b)`` instead of
731``PW_CHECK_INT_LE(a, b)`` or ``PW_CHECK_FLOAT_EXACT_LE(a, b)`` is that to
732capture the arguments with the tokenizer, we need to know the types. Using the
733preprocessor, it is impossible to dispatch based on the types of ``a`` and
734``b``, so unfortunately having a separate macro for each of the types commonly
735asserted on is necessary.
736
737----------------------------
738Module Configuration Options
739----------------------------
740The following configurations can be adjusted via compile-time configuration of
741this module, see the
742:ref:`module documentation <module-structure-compile-time-configuration>` for
743more details.
744
745.. c:macro:: PW_ASSERT_ENABLE_DEBUG
746
747  Controls whether ``DCHECK`` and ``DASSERT`` are enabled.
748
749  This defaults to being disabled if ``NDEBUG`` is defined, else it is enabled
750  by default.
751
752.. c:macro:: PW_ASSERT_CAPTURE_VALUES
753
754  Controls whether the evaluated values of a CHECK statement are captured as
755  arguments to the final string. Disabling this will reduce code size at CHECK
756  callsites, but slightly reduces debugability.
757
758  This defaults to enabled.
759
760-------------
761Compatibility
762-------------
763The facade is compatible with both C and C++.
764
765----------------
766Roadmap & Status
767----------------
768The Pigweed assert subsystem consiststs of several modules that work in
769coordination. This module is the facade (API), then a number of backends are
770available to handle assert failures. Products can also define their own
771backends. In some cases, the backends will have backends (like
772``pw_log_tokenized``).
773
774Below is a brief summary of what modules are ready for use:
775
776Available Assert Backends
777=========================
778- ``pw_assert`` - **Stable** - The assert facade (this module). This module is
779  stable, and in production use. The documentation is comprehensive and covers
780  the functionality. There are (a) tests for the facade macro processing logic,
781  using a fake assert backend; and (b) compile tests to verify that the
782  selected backend compiles with all supported assert constructions and types.
783- ``pw_assert_basic`` - **Stable** - The assert basic module is a simple assert
784  handler that displays the failed assert line and the values of captured
785  arguments. Output is directed to ``pw_sys_io``. This module is a great
786  ready-to-roll module when bringing up a system, but is likely not the best
787  choice for production.
788- ``pw_assert_log`` - **Stable** - This assert backend redirects to logging,
789  but with a logging flag set that indicates an assert failure. This is our
790  advised approach to get **tokenized asserts**--by using tokenized logging,
791  then using the ``pw_assert_log`` backend.
792
793Note: If one desires a null assert module (where asserts are removed), use
794``pw_assert_log`` in combination with ``pw_log_null``. This will direct asserts
795to logs, then the logs are removed due to the null backend.
796
797Missing Functionality
798=====================
799- **Stack traces** - Pigweed doesn't have a reliable stack walker, which makes
800  displaying a stack trace on crash harder. We plan to add this eventually.
801- **Snapshot integration** - Pigweed doesn't yet have a rich system state
802  capture system that can capture state like number of tasks, available memory,
803  and so on. Snapshot facilities are the obvious ones to run inside an assert
804  handler. It'll happen someday.
805