tests: fatal: increase coverage
- _SysFatalErrorHandler is supposed to be user-overridable. The test case now installs its own handler to show that this has happened properly. - Use TC_PRINT() TC_ERROR() macros - Since we have out own _SysFatalErrorHandler, show that k_panic() works - Show that _SysFatalErrorHandler gets invoked with the expected reason code for some of the scenarios. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
6255d6c6de
commit
000429c069
1 changed files with 85 additions and 20 deletions
|
@ -25,6 +25,27 @@ static char *overflow_stack = alt_stack + (STACKSIZE - OVERFLOW_STACKSIZE);
|
|||
static struct k_thread alt_thread;
|
||||
volatile int rv;
|
||||
|
||||
static volatile int crash_reason;
|
||||
|
||||
/* ARM is a special case, in that k_thread_abort() does indeed return
|
||||
* instead of calling _Swap() directly. The PendSV exception is queued
|
||||
* and immediately fires upon completing the exception path; the faulting
|
||||
* thread is never run again.
|
||||
*/
|
||||
#ifndef CONFIG_ARM
|
||||
FUNC_NORETURN
|
||||
#endif
|
||||
void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf)
|
||||
{
|
||||
TC_PRINT("Caught system error -- reason %d\n", reason);
|
||||
crash_reason = reason;
|
||||
|
||||
k_thread_abort(_current);
|
||||
#ifndef CONFIG_ARM
|
||||
CODE_UNREACHABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void alt_thread1(void)
|
||||
{
|
||||
#if defined(CONFIG_X86)
|
||||
|
@ -52,15 +73,26 @@ void alt_thread2(void)
|
|||
|
||||
key = irq_lock();
|
||||
k_oops();
|
||||
TC_ERROR("SHOULD NEVER SEE THIS\n");
|
||||
rv = TC_FAIL;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
void alt_thread3(void)
|
||||
{
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
k_panic();
|
||||
TC_ERROR("SHOULD NEVER SEE THIS\n");
|
||||
rv = TC_FAIL;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
void blow_up_stack(void)
|
||||
{
|
||||
char buf[OVERFLOW_STACKSIZE];
|
||||
printk("posting %zu bytes of junk to stack...\n", sizeof(buf));
|
||||
TC_PRINT("posting %zu bytes of junk to stack...\n", sizeof(buf));
|
||||
memset(buf, 0xbb, sizeof(buf));
|
||||
}
|
||||
|
||||
|
@ -68,9 +100,9 @@ void stack_thread1(void)
|
|||
{
|
||||
/* Test that stack overflow check due to timer interrupt works */
|
||||
blow_up_stack();
|
||||
printk("busy waiting...\n");
|
||||
TC_PRINT("busy waiting...\n");
|
||||
k_busy_wait(1024 * 1024);
|
||||
printk("should never see this\n");
|
||||
TC_ERROR("should never see this\n");
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
|
||||
|
@ -81,9 +113,9 @@ void stack_thread2(void)
|
|||
|
||||
/* Test that stack overflow check due to swap works */
|
||||
blow_up_stack();
|
||||
printk("swapping...\n");
|
||||
TC_PRINT("swapping...\n");
|
||||
_Swap(irq_lock());
|
||||
printk("should never see this\n");
|
||||
TC_ERROR("should never see this\n");
|
||||
rv = TC_FAIL;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
@ -97,31 +129,55 @@ void main(void)
|
|||
|
||||
k_thread_priority_set(_current, K_PRIO_PREEMPT(MAIN_PRIORITY));
|
||||
|
||||
printk("test alt thread 1: generic CPU exception\n");
|
||||
TC_PRINT("test alt thread 1: generic CPU exception\n");
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
(k_thread_entry_t)alt_thread1,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
TC_ERROR("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
printk("test alt thread 2: initiate kernel oops\n");
|
||||
TC_PRINT("test alt thread 2: initiate kernel oops\n");
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
(k_thread_entry_t)alt_thread2,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
k_thread_abort(&alt_thread);
|
||||
if (crash_reason != _NANO_ERR_KERNEL_OOPS) {
|
||||
TC_ERROR("bad reason code got %d expected %d\n",
|
||||
crash_reason, _NANO_ERR_KERNEL_OOPS);
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
TC_ERROR("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
printk("test stack overflow - timer irq\n");
|
||||
TC_PRINT("test alt thread 3: initiate kernel panic\n");
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
(k_thread_entry_t)alt_thread3,
|
||||
NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
k_thread_abort(&alt_thread);
|
||||
if (crash_reason != _NANO_ERR_KERNEL_PANIC) {
|
||||
TC_ERROR("bad reason code got %d expected %d\n",
|
||||
crash_reason, _NANO_ERR_KERNEL_PANIC);
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
if (rv == TC_FAIL) {
|
||||
TC_ERROR("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
TC_PRINT("test stack overflow - timer irq\n");
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
/* When testing stack sentinel feature, the overflow stack is a
|
||||
* smaller section of alt_stack near the end.
|
||||
|
@ -135,14 +191,19 @@ void main(void)
|
|||
(k_thread_entry_t)stack_thread1,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
if (crash_reason != _NANO_ERR_STACK_CHK_FAIL) {
|
||||
TC_ERROR("bad reason code got %d expected %d\n",
|
||||
crash_reason, _NANO_ERR_KERNEL_PANIC);
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
TC_ERROR("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
printk("test stack overflow - swap\n");
|
||||
TC_PRINT("test stack overflow - swap\n");
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE,
|
||||
#else
|
||||
|
@ -151,13 +212,17 @@ void main(void)
|
|||
(k_thread_entry_t)stack_thread2,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
if (crash_reason != _NANO_ERR_STACK_CHK_FAIL) {
|
||||
TC_ERROR("bad reason code got %d expected %d\n",
|
||||
crash_reason, _NANO_ERR_KERNEL_PANIC);
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
TC_ERROR("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
out:
|
||||
TC_END_RESULT(rv);
|
||||
TC_END_REPORT(rv);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue