Skip to content
Permalink
Browse files

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>
  • Loading branch information...
andrewboie committed Aug 6, 2019
1 parent 00bf76e commit f2422f1f19cff69eda0909554b0846cb3712e91f
@@ -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);
}
}

/**
@@ -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
}
@@ -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
@@ -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);
@@ -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
}

/**
@@ -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 */
@@ -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)

0 comments on commit f2422f1

Please sign in to comment.
You can’t perform that action at this time.