Skip to content

Commit

Permalink
Merge #19766
Browse files Browse the repository at this point in the history
19766: core/lib: make the use of DEBUG_BREAKPOINT on assert optional r=gschorcht a=gschorcht

### Contribution description

This PR makes the use of `DEBUG_BREAKPOINT` on failed assertion optional.

The behavior of `assert` has been changed with PR #19368. Instead of printing some useful information, either a breakpoint is inserted and the execution of the MCU stops in debugger or a endless while loop is executed.

Before PR #19368 the user got on failed assertion:
```
Starting ESP32x with ID: 7cdfa1e36a34
ESP-IDF SDK Version v4.4.1-0-g1329b19fe49
...
*** RIOT kernel panic:
FAILED ASSERTION.

*** halted.
```
This was very helpful during development, especially to identify quickly the cause of problems with `DEBUG_ASSERT_VERBOSE` enabled, e.g. when misconfiguration led to failed assertions.

With PR #19368 the user gets an address in best case (or even `0` on platforms like ESP32), in worst case the MCU seems to stuck, e.g.
```
Starting ESP32x with ID: 7cdfa1e36a34
ESP-IDF SDK Version v4.4.1-0-g1329b19fe49
...
0
```
The problem with the new behavior is that
- a user doesn't get a quick indication of what happened
- there is not always an easy way to attach a debugger

This PR therefore makes the use of `DEBUG_BREAKPOINT` optional using `DEBUG_ASSERT_BREAKPOINT` define.

### Testing procedure

Add `assert(0)` in `examples/hello-world/main.c` and compile with and w/o `CFLAGS='-DDEBUG_ASSERT_BREAKPOINT'`.

With `DEBUG_ASSERT_BREAKPOINT` the execution should stop in `assert_failue`. Without `DEBUG_ASSERT_BREAKPOINT`, the information as generated before PR #19368 and the execution should stop in `panic_arch`.

### Issues/PRs references



Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
  • Loading branch information
bors[bot] and gschorcht committed Jun 28, 2023
2 parents 117c577 + 6eb358b commit d339984
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/lib/assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ __NORETURN void _assert_failure(const char *file, unsigned line)
printf("failed assertion. Backtrace:\n");
backtrace_print();
#endif
#ifdef DEBUG_ASSERT_BREAKPOINT
DEBUG_BREAKPOINT(1);
#endif
core_panic(PANIC_ASSERT_FAIL, "FAILED ASSERTION.");
}

Expand All @@ -41,7 +43,9 @@ __NORETURN void _assert_panic(void)
#if IS_USED(MODULE_BACKTRACE)
backtrace_print();
#endif
#ifdef DEBUG_ASSERT_BREAKPOINT
DEBUG_BREAKPOINT(1);
#endif
core_panic(PANIC_ASSERT_FAIL, "FAILED ASSERTION.");
}

Expand Down
20 changes: 20 additions & 0 deletions core/lib/include/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ extern "C" {
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define DEBUG_ASSERT_VERBOSE

/**
* @brief Activate breakpoints for @ref assert() when defined
*
* Without this macro defined the @ref assert() macro will just print some
* information about the failed assertion, see @ref assert and
* @ref DEBUG_ASSERT_VERBOSE.
* If @ref DEBUG_ASSERT_BREAKPOINT is defined, the execution will stop on a
* failed assertion instead of producing the output. If the architecture
* defines the macro @ref DEBUG_BREAKPOINT, a breakpoint is inserted and the
* execution is stopped directly in the debugger. Otherwise the execution stops
* in an endless while loop.
*/
#define DEBUG_ASSERT_BREAKPOINT
#else
/* we should not include custom headers in standard headers */
#define _likely(x) __builtin_expect((uintptr_t)(x), 1)
Expand Down Expand Up @@ -112,6 +126,12 @@ __NORETURN void _assert_failure(const char *file, unsigned line);
* If the `backtrace` module is enabled (and implemented for architecture in use)
* a backtrace will be printed in addition to the location of the failed assertion.
*
* If @ref DEBUG_ASSERT_BREAKPOINT is defined, the execution will stop on a
* failed assertion instead of producing the above output. If the architecture
* defines the macro @ref DEBUG_BREAKPOINT, a breakpoint is inserted and the
* execution is stopped directly in the debugger. Otherwise the execution stops
* in an endless while loop.
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/assert.html
*/
#define assert(cond) (_likely(cond) ? (void)0 : _assert_failure(__FILE__, __LINE__))
Expand Down
4 changes: 4 additions & 0 deletions tests/sys/sema_inv/Makefile.ci
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-nano \
arduino-uno \
atmega328p \
atmega328p-xplained-mini \
nucleo-f031k6 \
nucleo-l011k4 \
#

0 comments on commit d339984

Please sign in to comment.