Files
zephyr/lib/os/thread_entry.c
Peter van der Perk 819955b52c kernel: thread: mark return undefined in z_thread_entry using DWARF
Add DWARF hint to handle z_thread_entry correctly
in debuggers. This function starts a new thread and never returns.
Use `.cfi_undefined` so DWARF-based unwinding does not rely on return.
Without this, unwinding may follow a bogus return address, leading to
invalid memory reads and potential bus faults during backtrace.

Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
2025-11-20 08:59:42 -05:00

71 lines
2.0 KiB
C

/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Thread entry
*
* This file provides the common thread entry function
*/
#include <zephyr/kernel.h>
#include <zephyr/arch/cfi.h>
#ifdef CONFIG_CURRENT_THREAD_USE_TLS
#include <zephyr/random/random.h>
Z_THREAD_LOCAL k_tid_t z_tls_current;
#endif
#ifdef CONFIG_STACK_CANARIES_TLS
extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
#endif /* CONFIG_STACK_CANARIES_TLS */
/*
* Common thread entry point function (used by all threads)
*
* This routine invokes the actual thread entry point function and passes
* it three arguments. It also handles graceful termination of the thread
* if the entry point function ever returns.
*
* This routine does not return, and is marked as such so the compiler won't
* generate preamble code that is only used by functions that actually return.
*/
FUNC_NORETURN void z_thread_entry(k_thread_entry_t entry,
void *p1, void *p2, void *p3)
{
/*
* Inform the unwinder that the current return address is undefined.
*
* This is typically used at points in the code where execution does not
* return like a normal function (for example, thread entry routines).
* Marking the return address as undefined prevents stack unwinding or
* backtrace tools from following a bogus return address, which could
* otherwise lead to reading invalid memory and cause faults during
* unwinding or debugging.
*/
ARCH_CFI_UNDEFINED_RETURN_ADDRESS();
#ifdef CONFIG_CURRENT_THREAD_USE_TLS
z_tls_current = k_sched_current_thread_query();
#endif
#ifdef CONFIG_STACK_CANARIES_TLS
uintptr_t stack_guard;
sys_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard));
__stack_chk_guard = stack_guard;
__stack_chk_guard <<= 8;
#endif /* CONFIG_STACK_CANARIES */
entry(p1, p2, p3);
k_thread_abort(k_current_get());
/*
* Compiler can't tell that k_thread_abort() won't return and issues a
* warning unless we tell it that control never gets this far.
*/
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
}