tests: clean up fatal error handlers

- k_sys_fatal_error_handler() can return on all platforms,
  indicating that the faulting thread should be aborted.
- Hang the system for unexpected faults instead of trying
  to keep going, we have no idea whether the system is even
  runnable.

Prevents infinite crash loops during tests.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2019-08-06 12:29:48 -07:00 committed by Andrew Boie
commit f2422f1f19
7 changed files with 32 additions and 46 deletions

View file

@ -50,8 +50,14 @@ static volatile int spur_handler_aborted_thread = 1;
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
{
zassert_equal(reason, K_ERR_SPURIOUS_IRQ, "wrong error reason");
zassert_equal(k_current_get(), &my_thread, "wrong thread crashed");
if (reason != K_ERR_SPURIOUS_IRQ) {
printk("wrong error reason\n");
k_fatal_halt(reason);
}
if (k_current_get() != &my_thread) {
printk("wrong thread crashed\n");
k_fatal_halt(reason);
}
}
/**

View file

@ -26,10 +26,6 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
valid_fault = false; /* reset back to normal */
ztest_test_pass();
} else {
ztest_test_fail();
k_fatal_halt(reason);
}
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
CODE_UNREACHABLE;
#endif
}

View file

@ -17,21 +17,10 @@
#define INFO(fmt, ...) printk(fmt, ##__VA_ARGS__)
/* ARM is a special case, in that k_thread_abort() does indeed return
* instead of calling z_swap() directly. The PendSV exception is queued
* and immediately fires upon completing the exception path; the faulting
* thread is never run again.
*/
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
FUNC_NORETURN
#endif
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
{
INFO("Caught system error -- reason %d\n", reason);
ztest_test_pass();
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
CODE_UNREACHABLE;
#endif
}
#ifdef CONFIG_CPU_CORTEX_M

View file

@ -17,7 +17,10 @@ ZTEST_BMEM static int ret = TC_PASS;
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
{
zassert_equal(reason, K_ERR_STACK_CHK_FAIL, "wrong error type");
if (reason != K_ERR_STACK_CHK_FAIL) {
printk("wrong error type\n");
k_fatal_halt(reason);
}
}
void check_input(const char *name, const char *input);

View file

@ -66,37 +66,27 @@ K_APP_BMEM(part0) static volatile unsigned int expected_reason;
*/
#define BARRIER() k_sem_give(&expect_fault_sem)
/* ARM is a special case, in that k_thread_abort() does indeed return
* instead of calling z_swap() directly. The PendSV exception is queued
* and immediately fires upon completing the exception path; the faulting
* thread is never run again.
*/
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
FUNC_NORETURN
#endif
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
{
INFO("Caught system error -- reason %d\n", reason);
/*
* If there is a user thread waiting for notification to exit,
* give it that notification.
*/
if (give_uthread_end_sem) {
give_uthread_end_sem = false;
k_sem_give(&uthread_end_sem);
}
if (expect_fault && expected_reason == reason) {
/*
* If there is a user thread waiting for notification to exit,
* give it that notification.
*/
if (give_uthread_end_sem) {
give_uthread_end_sem = false;
k_sem_give(&uthread_end_sem);
}
expect_fault = false;
expected_reason = 0;
BARRIER();
ztest_test_pass();
} else {
zassert_unreachable("Unexpected fault during test");
printk("Unexpected fault during test");
k_fatal_halt(reason);
}
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
CODE_UNREACHABLE;
#endif
}
/**

View file

@ -682,12 +682,8 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
valid_fault = false; /* reset back to normal */
ztest_test_pass();
} else {
ztest_test_fail();
k_fatal_halt(reason);
}
#if !(defined(CONFIG_ARM) || defined(CONFIG_ARC))
CODE_UNREACHABLE;
#endif
}
/******************************************************************************/
/* Test case entry points */

View file

@ -17,8 +17,14 @@ static ZTEST_BMEM struct k_thread *dyn_thread;
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
{
zassert_equal(reason, K_ERR_KERNEL_OOPS, "wrong error reason");
zassert_equal(k_current_get(), dyn_thread, "wrong thread crashed");
if (reason != K_ERR_KERNEL_OOPS) {
printk("wrong error reason\n");
k_fatal_halt(reason);
}
if (k_current_get() != dyn_thread) {
printk("wrong thread crashed\n");
k_fatal_halt(reason);
}
}
static void dyn_thread_entry(void *p1, void *p2, void *p3)