blob: 03c4fdad2701ceccb898e876c6bb3956d71eb947 [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
Wyatt Hepler3e57d822021-11-18 16:03:36 -080040 To ensure compatibility with :ref:`module-pw_assert_log` and
41 :ref:`module-pw_log_tokenized`, the message must be a string literal.
42
Keir Mierleec9bf1b2020-03-03 10:27:01 -080043Example
Erik Gilling40915502021-11-12 17:16:48 +000044=======
Keir Mierle3cee8792020-01-22 17:08:13 -080045
46.. code-block:: cpp
47
Wyatt Heplera59998f2021-03-19 14:35:10 -070048 #include "pw_assert/check.h"
Keir Mierle3cee8792020-01-22 17:08:13 -080049
50 int main() {
51 bool sensor_running = StartSensor(&msg);
52 PW_CHECK(sensor_running, "Sensor failed to start; code: %s", msg);
Keir Mierleec9bf1b2020-03-03 10:27:01 -080053
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());
Keir Mierle3cee8792020-01-22 17:08:13 -080058 }
59
Keir Mierleb9b88162020-04-15 20:43:09 -070060.. 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
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -080072 // This assert is enabled based on ``PW_ASSERT_ENABLE_DEBUG``.
Keir Mierleb9b88162020-04-15 20:43:09 -070073 // The functions ItemCount() and GetStateStr() are never called.
74 PW_DCHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr());
Keir Mierleec9bf1b2020-03-03 10:27:01 -080075
Keir Mierle854adec2020-09-03 14:07:19 -070076.. tip::
77
Wyatt Heplera59998f2021-03-19 14:35:10 -070078 Use ``PW_ASSERT`` from ``pw_assert/assert.h`` for asserts in headers or
Keir Mierle854adec2020-09-03 14:07:19 -070079 asserting in ``constexpr`` contexts.
80
Erik Gilling40915502021-11-12 17:16:48 +000081Structure of Assert Modules
82===========================
Keir Mierle481d8292020-07-31 01:10:05 -070083The 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
Wyatt Hepler1d221242021-09-07 15:42:21 -070094.. mermaid::
Wyatt Hepler79ea2cf2021-09-07 13:24:26 -070095
Wyatt Hepler1d221242021-09-07 15:42:21 -070096 graph LR
97 facade --> backend
Keir Mierle481d8292020-07-31 01:10:05 -070098
99See the Backend API section below for more details.
100
Keir Mierle854adec2020-09-03 14:07:19 -0700101----------
102Facade API
103----------
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800104The below functions describe the assert API functions that applications should
Wyatt Heplera59998f2021-03-19 14:35:10 -0700105invoke to assert. These macros are found in the ``pw_assert/check.h`` header.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800106
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, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700124.. cpp:function:: PW_DCHECK(condition)
125.. cpp:function:: PW_DCHECK(condition, format, ...)
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800126
127 Assert that a condition is true, optionally including a message with
128 arguments to report if the codition is false.
129
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800130 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
131 otherwise, the entire statement is removed (and the expression not evaluated).
Keir Mierleb9b88162020-04-15 20:43:09 -0700132
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700133 Example:
134
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800135 .. code-block:: cpp
136
137 PW_CHECK(StartTurbines());
138 PW_CHECK(StartWarpDrive(), "Oddly warp drive couldn't start; ruh-roh!");
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700139 PW_CHECK(RunSelfTest(), "Failure in self test; try %d", TestAttempts());
140
141 .. attention::
142
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700143 Don't use use ``PW_CHECK`` for binary comparisons or status checks!
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700144
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
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800150 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``.
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700153
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 +------------------------------------+-------------------------------------+
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700161 | ``PW_CHECK(Temp() <= 10.0)`` | ``PW_CHECK_FLOAT_EXACT_LE(`` |
162 | | `` Temp(), 10.0)`` |
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700163 +------------------------------------+-------------------------------------+
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800164 | ``PW_CHECK(Foo() == OkStatus())`` | ``PW_CHECK_OK(Foo())`` |
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700165 +------------------------------------+-------------------------------------+
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800166
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700167.. cpp:function:: PW_CHECK_NOTNULL(ptr)
168.. cpp:function:: PW_CHECK_NOTNULL(ptr, format, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700169.. cpp:function:: PW_DCHECK_NOTNULL(ptr)
170.. cpp:function:: PW_DCHECK_NOTNULL(ptr, format, ...)
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700171
172 Assert that the given pointer is not ``NULL``, optionally including a message
173 with arguments to report if the pointer is ``NULL``.
174
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800175 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
176 otherwise, the entire statement is removed (and the expression not evaluated).
Keir Mierleb9b88162020-04-15 20:43:09 -0700177
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700178 .. code-block:: cpp
179
180 Foo* foo = GetTheFoo()
181 PW_CHECK_NOTNULL(foo);
182
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700183 Bar* bar = GetSomeBar();
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700184 PW_CHECK_NOTNULL(bar, "Weirdly got NULL bar; state: %d", MyState());
185
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800186.. cpp:function:: PW_CHECK_TYPE_OP(a, b)
187.. cpp:function:: PW_CHECK_TYPE_OP(a, b, format, ...)
Keir Mierleb9b88162020-04-15 20:43:09 -0700188.. cpp:function:: PW_DCHECK_TYPE_OP(a, b)
189.. cpp:function:: PW_DCHECK_TYPE_OP(a, b, format, ...)
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800190
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
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800197 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
198 otherwise, the entire statement is removed (and the expression not evaluated).
Keir Mierleb9b88162020-04-15 20:43:09 -0700199
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800200 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
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700211 PW_CHECK_FLOAT_EXACT_GE(BatteryVoltage(), 3.2,
212 "System state=%s", SysState());
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800213
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
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700218 +-------------------------+--------------+-----------+-----------------------+
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 +-------------------------+--------------+-----------+-----------------------+
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800269
Keir Mierleb9b88162020-04-15 20:43:09 -0700270 The above ``CHECK_*_*()`` are also available in DCHECK variants, which will
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800271 only evaluate their arguments and trigger if the ``PW_ASSERT_ENABLE_DEBUG``
272 macro is enabled.
Keir Mierleb9b88162020-04-15 20:43:09 -0700273
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
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800347 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled;
348 otherwise, the entire statement is removed (and the expression not evaluated).
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700349
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
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800372 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is defined;
373 otherwise, the entire statement is removed (and the expression not evaluated).
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700374
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
Erik Gilling703abad2021-11-09 11:54:44 -0800394.. _module-pw_assert-assert-api:
395
Wyatt Heplera59998f2021-03-19 14:35:10 -0700396----------
397Assert API
398----------
Keir Mierle854adec2020-09-03 14:07:19 -0700399The 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
Wyatt Heplera59998f2021-03-19 14:35:10 -0700415**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**.
Keir Mierle854adec2020-09-03 14:07:19 -0700420
421Example
Erik Gilling40915502021-11-12 17:16:48 +0000422=======
Keir Mierle854adec2020-09-03 14:07:19 -0700423
424.. code-block:: cpp
425
426 // This example demonstrates asserting in a header.
427
Wyatt Heplera59998f2021-03-19 14:35:10 -0700428 #include "pw_assert/assert.h"
Keir Mierle854adec2020-09-03 14:07:19 -0700429
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
Erik Gilling40915502021-11-12 17:16:48 +0000444PW_ASSERT API Reference
445=======================
Keir Mierle854adec2020-09-03 14:07:19 -0700446.. 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
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800458 Same as ``PW_ASSERT()``, except that if ``PW_ASSERT_ENABLE_DEBUG == 0``, the
Keir Mierle854adec2020-09-03 14:07:19 -0700459 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
Alexei Frolov5a0450d2020-10-28 21:10:47 -0700466 when absolutely necessary**---in headers, constexpr contexts, or in rare cases
Keir Mierle854adec2020-09-03 14:07:19 -0700467 where the call site overhead of a full PW_CHECK must be avoided.
468
469 Use ``PW_CHECK_*()`` whenever possible.
470
Erik Gilling40915502021-11-12 17:16:48 +0000471PW_ASSERT API Backend
472=====================
Wyatt Heplera59998f2021-03-19 14:35:10 -0700473The ``PW_ASSERT`` API ultimately calls the C function
474``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert``
Wyatt Hepler66064662021-05-03 09:15:40 -0700475backend. The ``pw_assert_HandleFailure()`` function must not return.
Keir Mierle854adec2020-09-03 14:07:19 -0700476
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700477.. _module-pw_assert-circular-deps:
478
Erik Gilling40915502021-11-12 17:16:48 +0000479Avoiding Circular Dependencies With ``PW_ASSERT``
480=================================================
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700481Because asserts are so widely used, including in low-level libraries, it is
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700482common 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.
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700485
Wyatt Hepler61663222021-05-06 10:57:43 -0700486In 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`.
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700490
Wyatt Hepler61663222021-05-06 10:57:43 -0700491In 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``.
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700501
Armando Montanez179aa8e2021-03-10 11:46:35 -0800502.. _module-pw_assert-backend_api:
503
Keir Mierle854adec2020-09-03 14:07:19 -0700504-----------
505Backend API
506-----------
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800507The 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
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700512This facade module (``pw_assert``) does not provide a backend. See
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -0700513:ref:`module-pw_assert_basic` for a basic implementation.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800514
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700515.. attention::
516
517 The facade macros (``PW_CRASH`` and related) are expected to behave like they
Wyatt Hepler3d0e3152021-04-29 17:08:31 -0700518 have the ``[[noreturn]]`` attribute set. This implies that the backend handler
519 functions, ``PW_HANDLE_*`` defined by the backend, must not return.
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700520
521 In other words, the device must reboot.
522
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700523The backend must provide the header
524
525``pw_assert_backend/backend.h``
526
527and that header must define the following macros:
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800528
529.. cpp:function:: PW_HANDLE_CRASH(message, ...)
530
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700531 Trigger a system crash or halt, and if possible, deliver the specified
532 message and arguments to the user or developer.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800533
534.. cpp:function:: PW_HANDLE_ASSERT_FAILURE(condition_str, message, ...)
535
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700536 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.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800542
543.. cpp:function:: PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \
544 a_str, a_val, op_str, b_str, b_val, type_fmt, message, ...)
545
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700546 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.
Keir Mierleec9bf1b2020-03-03 10:27:01 -0800550
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700551 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
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -0700574 See :ref:`module-pw_assert_basic` for one way to combine these arguments
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700575 into a meaningful error message.
576
Wyatt Heplera59998f2021-03-19 14:35:10 -0700577Additionally, 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.
Keir Mierle854adec2020-09-03 14:07:19 -0700580
581.. cpp:function:: pw_assert_HandleFailure()
582
583 Handle a low-level crash. This crash entry happens through
Wyatt Heplera59998f2021-03-19 14:35:10 -0700584 ``pw_assert/assert.h``. In this crash handler, there is no access to line,
Keir Mierle854adec2020-09-03 14:07:19 -0700585 file, expression, or other rich assert information. Backends should do
586 something reasonable in this case; typically, capturing the stack is useful.
587
Erik Gilling40915502021-11-12 17:16:48 +0000588Backend Build Targets
589=====================
Wyatt Hepler61663222021-05-06 10:57:43 -0700590In 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`.
Wyatt Hepler8bd4fb02021-05-03 15:30:58 -0700597
Armando Montanez3d3e5382022-01-11 15:15:15 -0800598Macro-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
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700628--------------------------
Erik Gilling40915502021-11-12 17:16:48 +0000629Frequently Asked Questions
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700630--------------------------
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700631
Keir Mierle3f356722020-07-31 00:43:43 -0700632When should DCHECK_* be used instead of CHECK_* and vice versa?
Erik Gilling40915502021-11-12 17:16:48 +0000633===============================================================
Keir Mierle3f356722020-07-31 00:43:43 -0700634There 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
Keir Mierle481d8292020-07-31 01:10:05 -0700668 **Do not return error status codes for obvious API misuse**
Keir Mierle3f356722020-07-31 00:43:43 -0700669
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700670 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.
Keir Mierle3f356722020-07-31 00:43:43 -0700675
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700676 **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
Keir Mierle3f356722020-07-31 00:43:43 -0700679 mistake; so use error codes in those cases instead.
680
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700681How should objects be asserted against or compared?
Erik Gilling40915502021-11-12 17:16:48 +0000682===================================================
Shiva Rajagopal9e516562021-05-11 17:04:15 -0700683Unfortunately, there is no native mechanism for this, and instead the way to
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700684assert object states or comparisons is with the normal ``PW_CHECK_*`` macros
685that operate on booleans, ints, and floats.
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700686
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700687This is due to the requirement of supporting C and also tokenization. It may be
Shiva Rajagopal9e516562021-05-11 17:04:15 -0700688possible support rich object comparisons by defining a convention for
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700689stringifying 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?
Erik Gilling40915502021-11-12 17:16:48 +0000696============================================
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700697The 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?
Erik Gilling40915502021-11-12 17:16:48 +0000729=========================================================================
Keir Mierle49f8e7e2020-07-30 17:57:30 -0700730The 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.
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700736
Ewout van Bekkum2aff88e2021-11-12 15:36:57 -0800737----------------------------
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
Armando Montanezc8806f52021-11-19 10:43:07 -0800752.. 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
Keir Mierlec1cb12d2020-06-01 11:59:41 -0700760-------------
761Compatibility
762-------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700763The facade is compatible with both C and C++.
764
765----------------
766Roadmap & Status
767----------------
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700768The Pigweed assert subsystem consiststs of several modules that work in
Keir Mierle854adec2020-09-03 14:07:19 -0700769coordination. 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``).
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700773
Keir Mierle854adec2020-09-03 14:07:19 -0700774Below is a brief summary of what modules are ready for use:
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700775
Erik Gilling40915502021-11-12 17:16:48 +0000776Available Assert Backends
777=========================
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700778- ``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.
Keir Mierle854adec2020-09-03 14:07:19 -0700788- ``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.
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700792
Keir Mierle854adec2020-09-03 14:07:19 -0700793Note: 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.
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700796
Erik Gilling40915502021-11-12 17:16:48 +0000797Missing Functionality
798=====================
Keir Mierle77d3cbd2020-08-03 21:14:38 -0700799- **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.