1.. _module-pw_assert: 2 3========= 4pw_assert 5========= 6.. pigweed-module:: 7 :name: pw_assert 8 9-------- 10Overview 11-------- 12Pigweed's assert module enables applications to check preconditions, triggering 13a crash if the condition is not met. Consistent use of asserts is one aspect of 14defensive programming that can lead to more reliable and less buggy code. 15 16The assert API facilitates flexible crash handling through Pigweed's facade 17mechanism. The API is designed to enable features like: 18 19- Optional ancillary printf-style messages along assertions 20- Capturing actual values of binary operator assertions like ``a < b`` 21- Compatibility with pw_tokenizer for reduced binary code size 22 23The ``pw_assert`` API provides three classes of macros: 24 25- **PW_CRASH(format, ...)** - Trigger a crash with a message. 26- **PW_CHECK(condition[, format, ...])** - Assert a condition, optionally with 27 a message. 28- **PW_CHECK_<type>_<cmp>(a, b[, fmt, ...])** - Assert that the expression ``a 29 <cmp> b`` is true, optionally with a message. 30- **PW_ASSERT(condition)** - Header- and constexpr-safe assert. 31 32.. tip:: 33 34 All of the ``CHECK`` macros optionally support a message with additional 35 arguments, to assist in debugging when an assert triggers: 36 37 .. code-block:: cpp 38 39 PW_CHECK_INT_LE(ItemCount(), 100); 40 PW_CHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr()); 41 42 To ensure compatibility with :ref:`module-pw_assert_log` and 43 :ref:`module-pw_log_tokenized`, the message must be a string literal. 44 45Example 46======= 47 48.. code-block:: cpp 49 50 #include "pw_assert/check.h" 51 52 int main() { 53 bool sensor_running = StartSensor(&msg); 54 PW_CHECK(sensor_running, "Sensor failed to start; code: %s", msg); 55 56 int temperature_c = ReadSensorCelcius(); 57 PW_CHECK_INT_LE(temperature_c, 100, 58 "System is way out of heat spec; state=%s", 59 ReadSensorStateString()); 60 } 61 62.. tip:: 63 64 All macros have both a ``CHECK`` and ``DCHECK`` variant. The ``CHECK`` 65 variant is always enabled, even in production. Generally, we advise making 66 most asserts ``CHECK`` rather than ``DCHECK``, unless there is a critical 67 performance or code size reason to use ``DCHECK``. 68 69 .. code-block:: cpp 70 71 // This assert is always enabled, even in production. 72 PW_CHECK_INT_LE(ItemCount(), 100); 73 74 // This assert is enabled based on ``PW_ASSERT_ENABLE_DEBUG``. 75 // The functions ItemCount() and GetStateStr() are never called. 76 PW_DCHECK_INT_LE(ItemCount(), 100, "System state: %s", GetStateStr()); 77 78.. tip:: 79 80 Use ``PW_ASSERT`` from ``pw_assert/assert.h`` for asserts in headers or 81 asserting in ``constexpr`` contexts. 82 83Structure of Assert Modules 84=========================== 85The module is split into two components: 86 871. The **facade** (this module) which is only a macro interface layer, and 88 performs the actual checks for the conditions. 892. The **backend**, provided elsewhere, that handles the consequences of an 90 assert failing. Example backends include ``pw_assert_basic``, which prints a 91 useful message and either quits the application (on host) or hangs in a 92 while loop (on device). In the future, there will be a tokenized assert 93 backend. This is also where application or product specific crash handling 94 would go. 95 96.. mermaid:: 97 98 graph LR 99 facade --> backend 100 101See the Backend API section below for more details. 102 103---------- 104Facade API 105---------- 106The below functions describe the assert API functions that applications should 107invoke to assert. These macros are found in the ``pw_assert/check.h`` header. 108 109.. cpp:function:: PW_CRASH(format, ...) 110 111 Trigger a crash with a message. Replaces LOG_FATAL() in other systems. Can 112 include a message with format arguments; for example: 113 114 .. code-block:: cpp 115 116 PW_CRASH("Unexpected: frobnitz in state: %s", frobnitz_state); 117 118 Note: ``PW_CRASH`` is the equivalent of ``LOG_FATAL`` in other systems, where 119 a device crash is triggered with a message. In Pigweed, logging and 120 crashing/asserting are separated. There is a ``LOG_CRITICAL`` level in the 121 logging module, but it does not have side effects; for ``LOG_FATAL``, instead 122 use this macro (``PW_CRASH``). 123 124.. cpp:function:: PW_CHECK(condition) 125.. cpp:function:: PW_CHECK(condition, format, ...) 126.. cpp:function:: PW_DCHECK(condition) 127.. cpp:function:: PW_DCHECK(condition, format, ...) 128 129 Assert that a condition is true, optionally including a message with 130 arguments to report if the codition is false. 131 132 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled; 133 otherwise, the entire statement is removed (and the expression not evaluated). 134 135 Example: 136 137 .. code-block:: cpp 138 139 PW_CHECK(StartTurbines()); 140 PW_CHECK(StartWarpDrive(), "Oddly warp drive couldn't start; ruh-roh!"); 141 PW_CHECK(RunSelfTest(), "Failure in self test; try %d", TestAttempts()); 142 143 .. attention:: 144 145 Don't use use ``PW_CHECK`` for binary comparisons or status checks! 146 147 Instead, use the ``PW_CHECK_<TYPE>_<OP>`` macros. These macros enable 148 capturing the value of the operands, and also tokenizing them if using a 149 tokenizing assert backend. For example, if ``x`` and ``b`` are integers, 150 use instead ``PW_CHECK_INT_LT(x, b)``. 151 152 Additionally, use ``PW_CHECK_OK(status)`` when checking for an OK status, 153 since it enables showing a human-readable status string rather than an 154 integer (e.g. ``status == RESOURCE_EXHAUSTED`` instead of ``status == 5``. 155 This works with any expression convertible to ``pw::Status``, including 156 ``pw::StatusWithString`` and ``pw::Result<T>``. 157 158 +------------------------------------+-------------------------------------+ 159 | **Do NOT do this** | **Do this instead** | 160 +------------------------------------+-------------------------------------+ 161 | ``PW_CHECK(a_int < b_int)`` | ``PW_CHECK_INT_LT(a_int, b_int)`` | 162 +------------------------------------+-------------------------------------+ 163 | ``PW_CHECK(a_ptr <= b_ptr)`` | ``PW_CHECK_PTR_LE(a_ptr, b_ptr)`` | 164 +------------------------------------+-------------------------------------+ 165 | ``PW_CHECK(Temp() <= 10.0)`` | ``PW_CHECK_FLOAT_EXACT_LE(`` | 166 | | `` Temp(), 10.0)`` | 167 +------------------------------------+-------------------------------------+ 168 | ``PW_CHECK(Foo() == OkStatus())`` | ``PW_CHECK_OK(Foo())`` | 169 +------------------------------------+-------------------------------------+ 170 171.. cpp:function:: PW_CHECK_NOTNULL(ptr) 172.. cpp:function:: PW_CHECK_NOTNULL(ptr, format, ...) 173.. cpp:function:: PW_DCHECK_NOTNULL(ptr) 174.. cpp:function:: PW_DCHECK_NOTNULL(ptr, format, ...) 175 176 Assert that the given pointer is not ``NULL``, optionally including a message 177 with arguments to report if the pointer is ``NULL``. 178 179 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled; 180 otherwise, the entire statement is removed (and the expression not evaluated). 181 182 .. code-block:: cpp 183 184 Foo* foo = GetTheFoo() 185 PW_CHECK_NOTNULL(foo); 186 187 Bar* bar = GetSomeBar(); 188 PW_CHECK_NOTNULL(bar, "Weirdly got NULL bar; state: %d", MyState()); 189 190.. cpp:function:: PW_CHECK_TYPE_OP(a, b) 191.. cpp:function:: PW_CHECK_TYPE_OP(a, b, format, ...) 192.. cpp:function:: PW_DCHECK_TYPE_OP(a, b) 193.. cpp:function:: PW_DCHECK_TYPE_OP(a, b, format, ...) 194 195 Asserts that ``a OP b`` is true, where ``a`` and ``b`` are converted to 196 ``TYPE``; with ``OP`` and ``TYPE`` described below. 197 198 If present, the optional format message is reported on failure. Depending on 199 the backend, values of ``a`` and ``b`` will also be reported. 200 201 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled; 202 otherwise, the entire statement is removed (and the expression not evaluated). 203 204 Example, with no message: 205 206 .. code-block:: cpp 207 208 PW_CHECK_INT_LE(CurrentTemperature(), 100); 209 PW_CHECK_INT_LE(ItemCount(), 100); 210 211 Example, with an included message and arguments: 212 213 .. code-block:: cpp 214 215 PW_CHECK_FLOAT_EXACT_GE(BatteryVoltage(), 3.2, 216 "System state=%s", SysState()); 217 218 Below is the full list of binary comparison assert macros, along with the 219 type specifier. The specifier is irrelevant to application authors but is 220 needed for backend implementers. 221 222 +-------------------------+--------------+-----------+-----------------------+ 223 | Macro | a, b type | condition | a, b format specifier | 224 +-------------------------+--------------+-----------+-----------------------+ 225 | PW_CHECK_INT_LE | int | a <= b | %d | 226 +-------------------------+--------------+-----------+-----------------------+ 227 | PW_CHECK_INT_LT | int | a < b | %d | 228 +-------------------------+--------------+-----------+-----------------------+ 229 | PW_CHECK_INT_GE | int | a >= b | %d | 230 +-------------------------+--------------+-----------+-----------------------+ 231 | PW_CHECK_INT_GT | int | a > b | %d | 232 +-------------------------+--------------+-----------+-----------------------+ 233 | PW_CHECK_INT_EQ | int | a == b | %d | 234 +-------------------------+--------------+-----------+-----------------------+ 235 | PW_CHECK_INT_NE | int | a != b | %d | 236 +-------------------------+--------------+-----------+-----------------------+ 237 | PW_CHECK_UINT_LE | unsigned int | a <= b | %u | 238 +-------------------------+--------------+-----------+-----------------------+ 239 | PW_CHECK_UINT_LT | unsigned int | a < b | %u | 240 +-------------------------+--------------+-----------+-----------------------+ 241 | PW_CHECK_UINT_GE | unsigned int | a >= b | %u | 242 +-------------------------+--------------+-----------+-----------------------+ 243 | PW_CHECK_UINT_GT | unsigned int | a > b | %u | 244 +-------------------------+--------------+-----------+-----------------------+ 245 | PW_CHECK_UINT_EQ | unsigned int | a == b | %u | 246 +-------------------------+--------------+-----------+-----------------------+ 247 | PW_CHECK_UINT_NE | unsigned int | a != b | %u | 248 +-------------------------+--------------+-----------+-----------------------+ 249 | PW_CHECK_PTR_LE | void* | a <= b | %p | 250 +-------------------------+--------------+-----------+-----------------------+ 251 | PW_CHECK_PTR_LT | void* | a < b | %p | 252 +-------------------------+--------------+-----------+-----------------------+ 253 | PW_CHECK_PTR_GE | void* | a >= b | %p | 254 +-------------------------+--------------+-----------+-----------------------+ 255 | PW_CHECK_PTR_GT | void* | a > b | %p | 256 +-------------------------+--------------+-----------+-----------------------+ 257 | PW_CHECK_PTR_EQ | void* | a == b | %p | 258 +-------------------------+--------------+-----------+-----------------------+ 259 | PW_CHECK_PTR_NE | void* | a != b | %p | 260 +-------------------------+--------------+-----------+-----------------------+ 261 | PW_CHECK_FLOAT_EXACT_LE | float | a <= b | %f | 262 +-------------------------+--------------+-----------+-----------------------+ 263 | PW_CHECK_FLOAT_EXACT_LT | float | a < b | %f | 264 +-------------------------+--------------+-----------+-----------------------+ 265 | PW_CHECK_FLOAT_EXACT_GE | float | a >= b | %f | 266 +-------------------------+--------------+-----------+-----------------------+ 267 | PW_CHECK_FLOAT_EXACT_GT | float | a > b | %f | 268 +-------------------------+--------------+-----------+-----------------------+ 269 | PW_CHECK_FLOAT_EXACT_EQ | float | a == b | %f | 270 +-------------------------+--------------+-----------+-----------------------+ 271 | PW_CHECK_FLOAT_EXACT_NE | float | a != b | %f | 272 +-------------------------+--------------+-----------+-----------------------+ 273 274 The above ``CHECK_*_*()`` are also available in DCHECK variants, which will 275 only evaluate their arguments and trigger if the ``PW_ASSERT_ENABLE_DEBUG`` 276 macro is enabled. 277 278 +--------------------------+--------------+-----------+----------------------+ 279 | Macro | a, b type | condition | a, b format | 280 | | | | specifier | 281 +--------------------------+--------------+-----------+----------------------+ 282 | PW_DCHECK_INT_LE | int | a <= b | %d | 283 +--------------------------+--------------+-----------+----------------------+ 284 | PW_DCHECK_INT_LT | int | a < b | %d | 285 +--------------------------+--------------+-----------+----------------------+ 286 | PW_DCHECK_INT_GE | int | a >= b | %d | 287 +--------------------------+--------------+-----------+----------------------+ 288 | PW_DCHECK_INT_GT | int | a > b | %d | 289 +--------------------------+--------------+-----------+----------------------+ 290 | PW_DCHECK_INT_EQ | int | a == b | %d | 291 +--------------------------+--------------+-----------+----------------------+ 292 | PW_DCHECK_INT_NE | int | a != b | %d | 293 +--------------------------+--------------+-----------+----------------------+ 294 | PW_DCHECK_UINT_LE | unsigned int | a <= b | %u | 295 +--------------------------+--------------+-----------+----------------------+ 296 | PW_DCHECK_UINT_LT | unsigned int | a < b | %u | 297 +--------------------------+--------------+-----------+----------------------+ 298 | PW_DCHECK_UINT_GE | unsigned int | a >= b | %u | 299 +--------------------------+--------------+-----------+----------------------+ 300 | PW_DCHECK_UINT_GT | unsigned int | a > b | %u | 301 +--------------------------+--------------+-----------+----------------------+ 302 | PW_DCHECK_UINT_EQ | unsigned int | a == b | %u | 303 +--------------------------+--------------+-----------+----------------------+ 304 | PW_DCHECK_UINT_NE | unsigned int | a != b | %u | 305 +--------------------------+--------------+-----------+----------------------+ 306 | PW_DCHECK_PTR_LE | void* | a <= b | %p | 307 +--------------------------+--------------+-----------+----------------------+ 308 | PW_DCHECK_PTR_LT | void* | a < b | %p | 309 +--------------------------+--------------+-----------+----------------------+ 310 | PW_DCHECK_PTR_GE | void* | a >= b | %p | 311 +--------------------------+--------------+-----------+----------------------+ 312 | PW_DCHECK_PTR_GT | void* | a > b | %p | 313 +--------------------------+--------------+-----------+----------------------+ 314 | PW_DCHECK_PTR_EQ | void* | a == b | %p | 315 +--------------------------+--------------+-----------+----------------------+ 316 | PW_DCHECK_PTR_NE | void* | a != b | %p | 317 +--------------------------+--------------+-----------+----------------------+ 318 | PW_DCHECK_FLOAT_EXACT_LE | float | a <= b | %f | 319 +--------------------------+--------------+-----------+----------------------+ 320 | PW_DCHECK_FLOAT_EXACT_LT | float | a < b | %f | 321 +--------------------------+--------------+-----------+----------------------+ 322 | PW_DCHECK_FLOAT_EXACT_GE | float | a >= b | %f | 323 +--------------------------+--------------+-----------+----------------------+ 324 | PW_DCHECK_FLOAT_EXACT_GT | float | a > b | %f | 325 +--------------------------+--------------+-----------+----------------------+ 326 | PW_DCHECK_FLOAT_EXACT_EQ | float | a == b | %f | 327 +--------------------------+--------------+-----------+----------------------+ 328 | PW_DCHECK_FLOAT_EXACT_NE | float | a != b | %f | 329 +--------------------------+--------------+-----------+----------------------+ 330 331.. attention:: 332 333 For float, proper comparator checks which take floating point 334 precision and ergo error accumulation into account are not provided on 335 purpose as this comes with some complexity and requires application 336 specific tolerances in terms of Units of Least Precision (ULP). Instead, 337 carefully consider how floating point precision and error impact the data 338 they are bounding and whether checks are appropriate. 339 340.. cpp:function:: PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance) 341.. cpp:function:: PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance, format, ...) 342.. cpp:function:: PW_DCHECK_FLOAT_NEAR(a, b, abs_tolerance) 343.. cpp:function:: PW_DCHECK_FLOAT_NEAR(a, b, abs_tolerance, format, ...) 344 345 Asserts that ``(a >= b - abs_tolerance) && (a <= b + abs_tolerance)`` is true, 346 where ``a``, ``b``, and ``abs_tolerance`` are converted to ``float``. 347 348 .. note:: 349 This also asserts that ``abs_tolerance >= 0``. 350 351 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is enabled; 352 otherwise, the entire statement is removed (and the expression not evaluated). 353 354 Example, with no message: 355 356 .. code-block:: cpp 357 358 PW_CHECK_FLOAT_NEAR(cos(0.0f), 1, 0.001); 359 360 Example, with an included message and arguments: 361 362 .. code-block:: cpp 363 364 PW_CHECK_FLOAT_NEAR(FirstOperation(), RedundantOperation(), 0.1, 365 "System state=%s", SysState()); 366 367.. cpp:function:: PW_CHECK_OK(status) 368.. cpp:function:: PW_CHECK_OK(status, format, ...) 369.. cpp:function:: PW_DCHECK_OK(status) 370.. cpp:function:: PW_DCHECK_OK(status, format, ...) 371 372 Assert that ``status`` evaluates to ``pw::OkStatus()`` (in C++) or 373 ``PW_STATUS_OK`` (in C). Optionally include a message with arguments to 374 report. 375 376 ``status`` can be a ``pw::Status``, or (in C++ only) any expression 377 convertible to ``pw::Status``, including ``pw::StatusWithString`` and 378 ``pw::Result<T>``. 379 380 The ``DCHECK`` variants only run if ``PW_ASSERT_ENABLE_DEBUG`` is defined; 381 otherwise, the entire statement is removed (and the expression not evaluated). 382 383 .. code-block:: cpp 384 385 pw::Status operation_status = DoSomeOperation(); 386 PW_CHECK_OK(operation_status); 387 388 // Any expression that evaluates to a pw::Status or pw_Status works. 389 PW_CHECK_OK(DoTheThing(), "System state: %s", SystemState()); 390 391 // pw::Result<T> works. 392 pw::Result<int> result = GetSomething(); 393 PW_CHECK_OK(result); 394 395 // C works too. 396 pw_Status c_status = DoMoreThings(); 397 PW_CHECK_OK(c_status, "System state: %s", SystemState()); 398 399 .. note:: 400 401 Using ``PW_CHECK_OK(status)`` instead of ``PW_CHECK(status == OkStatus())`` 402 enables displaying an error message with a string version of the error 403 code; for example ``status == RESOURCE_EXHAUSTED`` instead of ``status == 404 5``. 405 406``%`` in conditions 407=================== 408``PW_CHECK`` conditions cannot contain the ``%`` character (e.g. from the 409modulus operator), since it may be interpreted as a printf-style format 410specifier. Some backends (:ref:`module-pw_assert_tokenized` in particular) may 411include the condition in the format string as a size optimization. 412Unintentionally introducing an extra %-style argument could lead to problems, so 413``pw_assert`` prevents this. 414 415Using a % in a ``PW_CHECK`` condition causes errors like the following: 416 417.. code-block:: none 418 419 ../pw_assert/public/pw_assert/internal/check_impl.h:237:7: note: expanded from macro '_PW_CHECK_BINARY_ARG_HANDLER' 420 237 | arg_a_str arg_b_str); /* cannot use '%' here; call mod via a function */ \ 421 422To avoid errors like this, do not use ``%`` in ``PW_CHECK`` conditions. Modulus 423can be moved to a separate statement outside of the ``PW_CHECK`` or invoked via 424a function or `std::modulus 425<https://en.cppreference.com/w/cpp/utility/functional/modulus>`_. 426 427This restriction may be removed in the future (`b/235149326 428<https://issues.pigweed.dev/issues/235149326>`_) 429 430.. _module-pw_assert-assert-api: 431 432---------- 433Assert API 434---------- 435The normal ``PW_CHECK_*`` and ``PW_DCHECK_*`` family of macros are intended to 436provide rich debug information, like the file, line number, value of operands 437in boolean comparisons, and more. However, this comes at a cost: these macros 438depend directly on the backend headers, and may perform complicated call-site 439transformations like tokenization. 440 441There are several issues with the normal ``PW_CHECK_*`` suite of macros: 442 4431. ``PW_CHECK_*`` in headers can cause ODR violations in the case of tokenized 444 asserts, due to differing module choices. 4452. ``PW_CHECK_*`` is not constexpr-safe. 4463. ``PW_CHECK_*`` can cause code bloat with some backends; this is the tradeoff 447 to get rich assert information. 4484. ``PW_CHECK_*`` can trigger circular dependencies when asserts are used from 449 low-level contexts, like in ``<span>``. 450 451**PW_ASSERT** solves all of the above problems: No risk of ODR violations, are 452constexpr safe, and have a tiny call site footprint; and there is no header 453dependency on the backend preventing circular include issues. However, there 454are **no format messages, no captured line number, no captured file, no captured 455expression, or anything other than a binary indication of failure**. 456 457Since ``PW_ASSERT`` can be used in ``constexpr`` functions, assertions may fail 458during compilation. For example, the following code fails to compile due to a 459``PW_ASSERT`` in a constant expression: 460 461.. literalinclude:: assert_test.cc 462 :language: cpp 463 :linenos: 464 :start-after: pw_assert-constexpr-example 465 :end-before: pw_assert-constexpr-example 466 467The compiler reports the failed assertion as follows: 468 469.. code-block:: none 470 471 example.cc:6:15: error: constexpr variable 'kResult' must be initialized by a constant expression 472 6 | constexpr int kResult = DivideEvenNumberBy2(11); // This fails the PW_ASSERT! 473 | ^ ~~~~~~~~~~~~~~~~~~~~~~~ 474 example.cc:2:3: note: non-constexpr function 'PW_ASSERT_failed_in_constant_expression_' cannot be used in a constant expression 475 2 | PW_ASSERT(value % 2 == 0); // value must be even! 476 | ^ 477 ../pw_assert/public/pw_assert/assert.h:33:7: note: expanded from macro 'PW_ASSERT' 478 33 | PW_ASSERT_failed_in_constant_expression_(); \ 479 | ^ 480 example.cc:6:25: note: in call to 'DivideEvenNumberBy2(11)' 481 6 | constexpr int kResult = DivideEvenNumberBy2(11); // This fails the PW_ASSERT! 482 | ^~~~~~~~~~~~~~~~~~~~~~~ 483 ../pw_assert/public/pw_assert/assert.h:88:20: note: declared here 484 88 | static inline void PW_ASSERT_failed_in_constant_expression_(void) {} 485 486Example 487======= 488 489.. code-block:: cpp 490 491 // This example demonstrates asserting in a header. 492 493 #include "pw_assert/assert.h" 494 495 class InlinedSubsystem { 496 public: 497 void DoSomething() { 498 // GOOD: No problem; PW_ASSERT is fine to inline and place in a header. 499 PW_ASSERT(IsEnabled()); 500 } 501 void DoSomethingElse() { 502 // BAD: Generally avoid using PW_DCHECK() or PW_CHECK in headers. If you 503 // want rich asserts or logs, move the function into the .cc file, and 504 // then use PW_CHECK there. 505 PW_DCHECK(IsEnabled()); // DON'T DO THIS 506 } 507 }; 508 509PW_ASSERT API Reference 510======================= 511.. cpp:function:: PW_ASSERT(condition) 512 513 A header- and constexpr-safe version of ``PW_CHECK()``. 514 515 If the given condition is false, crash the system. Otherwise, do nothing. 516 The condition is guaranteed to be evaluated. This assert implementation is 517 guaranteed to be constexpr-safe. 518 519.. cpp:function:: PW_DASSERT(condition) 520 521 A header- and constexpr-safe version of ``PW_DCHECK()``. 522 523 Same as ``PW_ASSERT()``, except that if ``PW_ASSERT_ENABLE_DEBUG == 0``, the 524 assert is disabled and condition is not evaluated. 525 526.. cpp:function:: PW_ASSERT_OK(expression) 527 528 A header- and constexpr-safe version of ``PW_CHECK_OK()``. 529 530 If the given expression is not `OK`, crash the system. Otherwise, do nothing. 531 The condition is guarenteed to be evaluated. 532 533.. attention:: 534 535 Unlike the ``PW_CHECK_*()`` suite of macros, ``PW_ASSERT()`` and 536 ``PW_DASSERT()`` capture no rich information like line numbers, the file, 537 expression arguments, or the stringified expression. Use these macros **only 538 when absolutely necessary**---in headers, constexpr contexts, or in rare cases 539 where the call site overhead of a full PW_CHECK must be avoided. 540 541 Use ``PW_CHECK_*()`` whenever possible. 542 543PW_ASSERT API Backend 544===================== 545The ``PW_ASSERT`` API ultimately calls the C function 546``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert`` 547backend. The ``pw_assert_HandleFailure()`` function must not return. 548 549.. _module-pw_assert-circular-deps: 550 551Avoiding Circular Dependencies With ``PW_ASSERT`` 552================================================= 553Because asserts are so widely used, including in low-level libraries, it is 554common for the ``pw_assert`` backend to cause circular dependencies. Because of 555this, assert backends may avoid declaring explicit dependencies, instead relying 556on include paths to access header files. 557 558GN 559-- 560In GN, the ``pw_assert`` backend's full implementation with true dependencies is 561made available through the ``$dir_pw_assert:impl`` group. When 562``pw_assert_BACKEND`` is set, ``$dir_pw_assert:impl`` must be listed in the 563``pw_build_LINK_DEPS`` variable. See :ref:`module-pw_build-link-deps`. 564 565In the ``pw_assert``, the backend's full implementation is placed in the 566``$pw_assert_BACKEND.impl`` target. ``$dir_pw_assert:impl`` depends on this 567backend target. The ``$pw_assert_BACKEND.impl`` target may be an empty group if 568the backend target can use its dependencies directly without causing circular 569dependencies. 570 571In order to break dependency cycles, the ``pw_assert_BACKEND`` target may need 572to directly provide dependencies through include paths only, rather than GN 573``public_deps``. In this case, GN header checking can be disabled with 574``check_includes = false``. 575 576Bazel 577----- 578In Bazel, assert backends may break dependency cycles by placing the full 579implementation in an ``impl`` target, like ``//pw_assert_basic:impl`` or 580``//pw_assert_tokenized:impl``. The ``//pw_assert:backend_impl`` label flag 581should be set to the ``impl`` target required by the assert backend used by the 582platform. 583 584You must add a dependency on the ``@pigweed//pw_assert:backend_impl`` target to 585any binary using ``pw_assert``. 586 587See :ref:`docs-build_system-bazel_link-extra-lib` for a general discussion of 588cyclic dependencies in low-level libraries in Bazel. 589 590.. _module-pw_assert-backend_api: 591 592----------- 593Backend API 594----------- 595The backend controls what to do in the case of an assertion failure. In the 596most basic cases, the backend could display the assertion failure on something 597like sys_io and halt in a while loop waiting for a debugger. In other cases, 598the backend could store crash details like the current thread's stack to flash. 599 600This facade module (``pw_assert``) does not provide a backend. See 601:ref:`module-pw_assert_basic` for a basic implementation. 602 603.. attention:: 604 605 The facade macros (``PW_CRASH`` and related) are expected to behave like they 606 have the ``[[noreturn]]`` attribute set. This implies that the backend handler 607 functions, ``PW_HANDLE_*`` defined by the backend, must not return. 608 609 In other words, the device must reboot. 610 611The backend must provide the header 612 613``pw_assert_backend/check_backend.h`` 614 615and that header must define the following macros: 616 617.. cpp:function:: PW_HANDLE_CRASH(message, ...) 618 619 Trigger a system crash or halt, and if possible, deliver the specified 620 message and arguments to the user or developer. 621 622.. cpp:function:: PW_HANDLE_ASSERT_FAILURE(condition_str, message, ...) 623 624 Trigger a system crash or halt, and if possible, deliver the condition string 625 (indicating what expression was false) and the message with format arguments, 626 to the user or developer. 627 628 This macro is invoked from the ``PW_CHECK`` facade macro if condition is 629 false. 630 631.. cpp:function:: PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \ 632 a_str, a_val, op_str, b_str, b_val, type_fmt, message, ...) 633 634 Trigger a system crash or halt for a failed binary comparison assert (e.g. 635 any of the ``PW_CHECK_<type>_<op>`` macros). The handler should combine the 636 assert components into a useful message for the user; though in some cases 637 this may not be possible. 638 639 Consider the following example: 640 641 .. code-block:: cpp 642 643 int temp = 16; 644 int max_temp = 15; 645 PW_CHECK_INT_LE(temp, MAX_TEMP, "Got too hot; state: %s", GetSystemState()); 646 647 In this block, the assert will trigger, which will cause the facade to invoke 648 the handler macro. Below is the meaning of the arguments, referencing to the 649 example: 650 651 - ``a_str`` - Stringified first operand. In the example: ``"temp"``. 652 - ``a_val`` - The value of the first operand. In the example: ``16``. 653 - ``op_str`` - The string version of the operator. In the example: "<=". 654 - ``b_str`` - Stringified second operand. In the example: ``"max_temp"``. 655 - ``b_val`` - The value of the second operand. In the example: ``15``. 656 - ``type_fmt`` - The format code for the type. In the example: ``"%d"``. 657 - ``message, ...`` - A formatted message to go with the assert. In the 658 example: ``"Got too hot; state: %s", "ON_FIRE"``. 659 660 .. tip:: 661 662 See :ref:`module-pw_assert_basic` for one way to combine these arguments 663 into a meaningful error message. 664 665Additionally, the backend must provide a link-time function for the 666``PW_ASSERT`` assert handler. This does not need to appear in the backend 667header, but instead is in a ``.cc`` file. 668 669.. cpp:function:: pw_assert_HandleFailure() 670 671 Handle a low-level crash. This crash entry happens through 672 ``pw_assert/assert.h``. In this crash handler, there is no access to line, 673 file, expression, or other rich assert information. Backends should do 674 something reasonable in this case; typically, capturing the stack is useful. 675 676Backend Build Targets 677===================== 678In GN, the backend must provide a ``pw_assert.impl`` build target in the same 679directory as the backend target. If the main backend target's dependencies would 680cause dependency cycles, the actual backend implementation with its full 681dependencies is placed in the ``pw_assert.impl`` target. If this is not 682necessary, ``pw_assert.impl`` can be an empty group. Circular dependencies are a 683common problem with ``pw_assert`` because it is so widely used. See 684:ref:`module-pw_assert-circular-deps`. 685 686Macro-based PW_ASSERT()/PW_DASSERT() backend 687============================================ 688The pw_assert API is being re-assessed to provide more helpful information in 689contexts where ``PW_CHECK_*()`` macros cannot be used. A first step towards this 690is providing a macro-based backend API for the ``PW_ASSERT()`` and 691``PW_DASSERT()`` macros. 692 693.. warning:: 694 This part of ``pw_assert``'s API is transitional, and any project-specific 695 reliance on any of the API mentioned here will likely experience breakages. 696 In particular, ``PW_ASSERT_HANDLE_FAILURE`` and ``PW_HANDLE_ASSERT_FAILURE`` 697 are extremely confusingly similar and are NOT interchangeable. 698 699A macro-based backend for the ``PW_ASSERT()`` macros must provide the following 700macro in a header at ``pw_assert_backend/assert_backend.h``. 701 702.. cpp:function:: PW_ASSERT_HANDLE_FAILURE(expression) 703 704 Handle a low-level crash. This crash entry happens through 705 ``pw_assert/assert.h``. Backends must ensure their implementation is safe for 706 usage in headers, constexpr contexts, and templates. This macro should expand 707 to an expression that does not return. 708 709Similar to the ``PW_CHECK_*()`` facade, the header backend that provides an 710expansion for the ``PW_ASSERT_HANDLE_FAILURE()`` macro can be controlled in the 711GN build using the ``pw_assert_LITE_BACKEND`` build argument. In addition to 712the header-based target at ``${pw_assert_LITE_BACKEND}``, a source set at 713``${pw_assert_LITE_BACKEND}.impl`` is also required as a way to reduce the 714impact of :ref:`circular dependencies <module-pw_assert-circular-deps>`. 715 716-------------------------- 717Frequently Asked Questions 718-------------------------- 719 720When should DCHECK_* be used instead of CHECK_* and vice versa? 721=============================================================== 722There is no hard and fast rule for when to use one or the other. 723 724In theory, ``DCHECK_*`` macros should never be used and all the asserts should 725remain active in production. In practice, **assert statements come at a binary 726size and runtime cost**, even when using extensions like a tokenized assert 727backend that strips the stringified assert expression from the binary. Each 728assert is **at least a branch with a function call**; depending on the assert 729backend, that function call may take several arguments (like the message, the 730file line number, the module, etc). These function calls can take 10-20 bytes 731or more of ROM each. Thus, there is a balance to be struct between ``DCHECK_*`` 732and ``CHECK_*``. 733 734Pigweed uses these conventions to decide between ``CHECK_*`` and ``DCHECK_*``: 735 736- **Prefer to use CHECK_* at public API boundaries** of modules, where an 737 invalid value is a clear programmer bug. In certain cases use ``DCHECK_*`` to 738 keep binary size small when in production; for example, in modules with a 739 large public API surface, or modules with many inlined functions in headers. 740- **Avoid using CHECK_* macros in headers.** It is still OK to use ``CHECK_*`` 741 macros in headers, but carefully consider the cost, since inlined use of the 742 ``CHECK_*`` macros in headers will expand to the full assert cost for every 743 translation unit that includes the header and calls the function with the 744 ``CHECK_*`` instance. ``DCHECK_*`` macros are are better, but even they come 745 at a cost, since it is preferable to be able to compile a binary in debug 746 mode for as long as possible on the road to production. 747- **Prefer to use DCHECK_* variants for internal asserts** that attempt to 748 catch module-author level programming errors. For example, use DCHECKs to 749 verify internal function preconditions, or other invariants that should 750 always be true but will likely never fire in production. In some cases using 751 ``CHECK_*`` macros for internal consistency checking can make sense, if the 752 runtime cost is low and there are only a couple of instances. 753 754.. tip:: 755 756 **Do not return error status codes for obvious API misuse** 757 758 Returning an error code may **mask the earliest sign of a bug** because 759 notifying the developer of the problem depends on correct propagation of the 760 error to upper levels of the system. Instead, prefer to use the ``CHECK_*`` 761 or ``DCHECK_*`` macros to ensure a prompt termination and warning to the 762 developer. 763 764 **Error status codes should be reserved for system misbehaviour or expected 765 exceptional cases**, like a sensor is not yet ready, or a storage subsystem 766 is full when writing. Doing ``CHECK_*`` assertions in those cases would be a 767 mistake; so use error codes in those cases instead. 768 769How should objects be asserted against or compared? 770=================================================== 771Unfortunately, there is no native mechanism for this, and instead the way to 772assert object states or comparisons is with the normal ``PW_CHECK_*`` macros 773that operate on booleans, ints, and floats. 774 775This is due to the requirement of supporting C and also tokenization. It may be 776possible support rich object comparisons by defining a convention for 777stringifying objects; however, this hasn't been added yet. Additionally, such a 778mechanism would not work well with tokenization. In particular, it would 779require runtime stringifying arguments and rendering them with ``%s``, which 780leads to binary bloat even with tokenization. So it is likely that a rich 781object assert API won't be added. 782 783Why was the assert facade designed this way? 784============================================ 785The Pigweed assert API was designed taking into account the needs of several 786past projects the team members were involved with. Based on those experiences, 787the following were key requirements for the API: 788 7891. **C compatibility** - Since asserts are typically invoked from arbitrary 790 contexts, including from vendor or third party code, the assert system must 791 have a C-compatible API. Some API functions working only in C++ is 792 acceptable, as long as the key functions work in C. 7932. **Capturing both expressions and values** - Since asserts can trigger in 794 ways that are not repeatable, it is important to capture rich diagnostic 795 information to help identifying the root cause of the fault. For asserts, 796 this means including the failing expression text, and optionally also 797 capturing failing expression values. For example, instead of capturing an 798 error with the expression (``x < y``), capturing an error with the 799 expression and values(``x < y, with x = 10, y = 0``). 8003. **Tokenization compatible** - It's important that the assert expressions 801 support tokenization; both the expression itself (e.g. ``a < b``) and the 802 message attached to the expression. For example: ``PW_CHECK(ItWorks(), "Ruh 803 roh: %d", some_int)``. 8044. **Customizable assert handling** - Most products need to support custom 805 handling of asserts. In some cases, an assert might trigger printing out 806 details to a UART; in other cases, it might trigger saving a log entry to 807 flash. The assert system must support this customization. 808 809The combination of #1, #2, and #3 led to the structure of the API. In 810particular, the need to support tokenized asserts and the need to support 811capturing values led to the choice of having ``PW_CHECK_INT_LE(a, b)`` instead 812of ``PW_CHECK(a <= b)``. Needing to support tokenization is what drove the 813facade & backend arrangement, since the backend must provide the raw macros for 814asserting in that case, rather than terminating at a C-style API. 815 816Why isn't there a ``PW_CHECK_LE``? Why is the type (e.g. ``INT``) needed? 817========================================================================= 818The problem with asserts like ``PW_CHECK_LE(a, b)`` instead of 819``PW_CHECK_INT_LE(a, b)`` or ``PW_CHECK_FLOAT_EXACT_LE(a, b)`` is that to 820capture the arguments with the tokenizer, we need to know the types. Using the 821preprocessor, it is impossible to dispatch based on the types of ``a`` and 822``b``, so unfortunately having a separate macro for each of the types commonly 823asserted on is necessary. 824 825---------------------------- 826Module Configuration Options 827---------------------------- 828The following configurations can be adjusted via compile-time configuration of 829this module, see the 830:ref:`module documentation <module-structure-compile-time-configuration>` for 831more details. 832 833.. c:macro:: PW_ASSERT_ENABLE_DEBUG 834 835 Controls whether ``DCHECK`` and ``DASSERT`` are enabled. 836 837 This defaults to being disabled if ``NDEBUG`` is defined, else it is enabled 838 by default. 839 840.. c:macro:: PW_ASSERT_CAPTURE_VALUES 841 842 Controls whether the evaluated values of a CHECK statement are captured as 843 arguments to the final string. Disabling this will reduce code size at CHECK 844 callsites, but slightly reduces debugability. 845 846 This defaults to enabled. 847 848------------- 849Compatibility 850------------- 851The facade is compatible with both C and C++. 852 853--------------------------------------- 854C Standard Library `assert` Replacement 855--------------------------------------- 856An optional replacement of the C standard Library's `assert` macro is provided 857through the `libc_assert` target which fully implements replacement `assert.h` 858and `cassert` headers using `PW_ASSERT`. While this is effective for porting 859external code to microcontrollers, we do not advise embedded projects use the 860`assert` macro unless absolutely necessary. 861 862---------------- 863Roadmap & Status 864---------------- 865The Pigweed assert subsystem consiststs of several modules that work in 866coordination. This module is the facade (API), then a number of backends are 867available to handle assert failures. Products can also define their own 868backends. In some cases, the backends will have backends (like 869``pw_log_tokenized``). 870 871Below is a brief summary of what modules are ready for use: 872 873Available Assert Backends 874========================= 875See :ref:`module-pw_assert-backends`. 876 877Missing Functionality 878===================== 879- **Stack traces** - Pigweed doesn't have a reliable stack walker, which makes 880 displaying a stack trace on crash harder. We plan to add this eventually. 881- **Snapshot integration** - Pigweed doesn't yet have a rich system state 882 capture system that can capture state like number of tasks, available memory, 883 and so on. Snapshot facilities are the obvious ones to run inside an assert 884 handler. It'll happen someday. 885 886.. toctree:: 887 :maxdepth: 1 888 889 backends 890