/* * Copyright (c) 2020 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #if defined(CONFIG_ZTEST_FATAL_HOOK) /* This is a flag indicate if treating fatal error as expected, then take * action dealing with it. It's SMP-safe. */ ZTEST_BMEM volatile bool fault_in_isr; ZTEST_BMEM volatile k_tid_t valid_fault_tid; static inline void reset_stored_fault_status(void) { valid_fault_tid = NULL; fault_in_isr = false; } void z_impl_ztest_set_fault_valid(bool valid) { if (valid) { if (k_is_in_isr()) { fault_in_isr = true; } else { valid_fault_tid = k_current_get(); } } else { reset_stored_fault_status(); } } #if defined(CONFIG_USERSPACE) static inline void z_vrfy_ztest_set_fault_valid(bool valid) { z_impl_ztest_set_fault_valid(valid); } #include #endif __weak void ztest_post_fatal_error_hook(unsigned int reason, const struct arch_esf *pEsf) { } void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *pEsf) { k_tid_t curr_tid = k_current_get(); bool valid_fault = (curr_tid == valid_fault_tid) || fault_in_isr; printk("Caught system error -- reason %d %d\n", reason, valid_fault); if (valid_fault) { printk("Fatal error expected as part of test case.\n"); /* reset back to normal */ reset_stored_fault_status(); /* do some action after expected fatal error happened */ ztest_post_fatal_error_hook(reason, pEsf); } else { printk("Fatal error was unexpected, aborting...\n"); k_fatal_halt(reason); } } #endif #if defined(CONFIG_ZTEST_ASSERT_HOOK) /* This is a flag indicate if treating assert fail as expected, then take * action dealing with it. It's SMP-safe. */ ZTEST_BMEM volatile bool assert_in_isr; ZTEST_BMEM volatile k_tid_t valid_assert_tid; static inline void reset_stored_assert_status(void) { valid_assert_tid = NULL; assert_in_isr = 0; } void z_impl_ztest_set_assert_valid(bool valid) { if (valid) { if (k_is_in_isr()) { assert_in_isr = true; } else { valid_assert_tid = k_current_get(); } } else { reset_stored_assert_status(); } } #if defined(CONFIG_USERSPACE) static inline void z_vrfy_ztest_set_assert_valid(bool valid) { z_impl_ztest_set_assert_valid(valid); } #include #endif __weak void ztest_post_assert_fail_hook(void) { k_thread_abort(k_current_get()); CODE_UNREACHABLE; } #ifdef CONFIG_ASSERT_NO_FILE_INFO void assert_post_action(void) #else void assert_post_action(const char *file, unsigned int line) #endif { #ifndef CONFIG_ASSERT_NO_FILE_INFO ARG_UNUSED(file); ARG_UNUSED(line); #endif printk("Caught assert failed\n"); if ((k_current_get() == valid_assert_tid) || assert_in_isr) { printk("Assert error expected as part of test case.\n"); /* reset back to normal */ reset_stored_assert_status(); /* It won't go back to caller when assert failed, and it * will terminate the thread. */ ztest_post_assert_fail_hook(); } else { printk("Assert failed was unexpected, aborting...\n"); #ifdef CONFIG_USERSPACE /* User threads aren't allowed to induce kernel panics; generate * an oops instead. */ if (k_is_user_context()) { k_oops(); } #endif k_panic(); } } #endif