Skip to content

Commit

Permalink
zephyr/wrapper.c: dereference NULL in POSIX for better k_panic() trace
Browse files Browse the repository at this point in the history
As discussed in the alternative approach
zephyrproject-rtos/zephyr#68494, k_panic() in
POSIX mode has various shortcomings that do not provide a useful
trace. Useless pointers to signal handlers or other cleanup routines are
printed instead. Leverage our already existing
k_sys_fatal_error_handler() and dereference a NULL pointer there when in
POSIX mode. This "fails fast" and provides a complete and relevant stack
trace in CI when fuzzing or when using some other static
analyzer. Example of how fuzzing failure thesofproject#8832 would have looked like in
CI results thanks to this commit:

```
./build-fuzz/zephyr/zephyr.exe: Running 1 inputs 1 time(s) each.
Running: ./rballoc_align_fuzz_crash
*** Booting Zephyr OS build zephyr-v3.5.0-3971-ge07de4e0a167 ***
[00:00:00.000,000] <inf> main: SOF on native_posix
[00:00:00.000,000] <inf> main: SOF initialized
@ WEST_TOPDIR/sof/zephyr/lib/alloc.c:391
[00:00:00.000,000] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic
[00:00:00.000,000] <err> os: Current thread: 0x891f8a0 (unknown)
[00:00:00.000,000] <err> zephyr: Halting emulation
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1784402==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000
==1784402==The signal is caused by a WRITE memory access.
==1784402==Hint: address points to the zero page.
    #0 0x829a77d in k_sys_fatal_error_handler zephyr/wrapper.c:352:19
    #1 0x829b8c0 in rballoc_align zephyr/lib/alloc.c:391:3
    thesofproject#2 0x8281438 in buffer_alloc src/audio/buffer.c:58:16
    thesofproject#3 0x826a60a in buffer_new src/ipc/ipc-helper.c:48:11
    thesofproject#4 0x8262107 in ipc_buffer_new src/ipc/ipc3/helper.c:459:11
    thesofproject#5 0x825944d in ipc_glb_tplg_buffer_new src/ipc/ipc3/handler.c:1305:8
    thesofproject#6 0x8257036 in ipc_cmd src/ipc/ipc3/handler.c:1651:9
    thesofproject#7 0x8272e59 in ipc_platform_do_cmd src/platform/posix/ipc.c:162:2
    thesofproject#8 0x826a2ac in ipc_do_cmd src/ipc/ipc-common.c:328:9
    thesofproject#9 0x829b0ab in task_run zephyr/include/rtos/task.h:94:9
    thesofproject#10 0x829abd8 in edf_work_handler zephyr/edf_schedule.c:32:16
    thesofproject#11 0x83560f7 in work_queue_main zephyr/kernel/work.c:688:3
    thesofproject#12 0x82244c2 in z_thread_entry zephyr/lib/os/thread_entry.c:48:2
```

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
  • Loading branch information
marc-hb committed Feb 27, 2024
1 parent 5753dba commit dcf6b6b
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions zephyr/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,32 @@ int poll_for_register_delay(uint32_t reg, uint32_t mask,
return 0;
}

/* Mutable, volatile and not static to escape optimizers and static
* analyzers.
*/
volatile int *_sof_fatal_null = NULL;

void k_sys_fatal_error_handler(unsigned int reason,
const z_arch_esf_t *esf)
{
ARG_UNUSED(esf);

/* flush and switch to immediate mode */
LOG_PANIC();

ipc_send_panic_notification();

#if defined(CONFIG_ARCH_POSIX) || defined(CONFIG_ZEPHYR_POSIX)
LOG_ERR("Halting emulation");

/* In emulation we want to stop _immediately_ and print a useful stack
* trace; not a useless pointer to some signal handler or Zephyr
* cleanup routine. See Zephyr POSIX limitations discussed in:
* https://github.com/zephyrproject-rtos/zephyr/pull/68494
*/
*_sof_fatal_null = 42;
#else
LOG_ERR("Halting system");
#endif
k_fatal_halt(reason);
}

0 comments on commit dcf6b6b

Please sign in to comment.