kernel: add k_panic() and k_oops() APIs

Unlike assertions, these APIs are active at all times. The kernel will
treat these errors in the same way as fatal CPU exceptions. Ultimately,
the policy of what to do with these errors is implemented in
_SysFatalErrorHandler.

If the archtecture supports it, a real CPU exception can be triggered
which will provide a complete register dump and PC value when the
problem occurs. This will provide more helpful information than a fake
exception stack frame (_default_esf) passed to the arch-specific exception
handling code.

Issue: ZEP-843
Change-Id: I8f136905c05bb84772e1c5ed53b8e920d24eb6fd
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-04-18 15:22:05 -07:00 committed by Anas Nashif
commit cdb94d6425
19 changed files with 192 additions and 81 deletions

View file

@ -17,13 +17,7 @@
#include <kernel.h>
#include <kernel_structs.h>
#ifdef CONFIG_PRINTK
#include <misc/printk.h>
#define PR_EXC(...) printk(__VA_ARGS__)
#else
#define PR_EXC(...)
#endif /* CONFIG_PRINTK */
/*
* Define a default ESF for use with _NanoFatalErrorHandler() in the event
@ -75,24 +69,32 @@ void _NanoFatalErrorHandler(unsigned int reason,
{
switch (reason) {
case _NANO_ERR_INVALID_TASK_EXIT:
PR_EXC("***** Invalid Exit Software Error! *****\n");
printk("***** Invalid Exit Software Error! *****\n");
break;
#if defined(CONFIG_STACK_CANARIES)
case _NANO_ERR_STACK_CHK_FAIL:
PR_EXC("***** Stack Check Fail! *****\n");
printk("***** Stack Check Fail! *****\n");
break;
#endif /* CONFIG_STACK_CANARIES */
case _NANO_ERR_ALLOCATION_FAIL:
PR_EXC("**** Kernel Allocation Failure! ****\n");
printk("**** Kernel Allocation Failure! ****\n");
break;
case _NANO_ERR_KERNEL_OOPS:
printk("***** Kernel OOPS! *****\n");
break;
case _NANO_ERR_KERNEL_PANIC:
printk("***** Kernel Panic! *****\n");
break;
default:
PR_EXC("**** Unknown Fatal Error %d! ****\n", reason);
printk("**** Unknown Fatal Error %d! ****\n", reason);
break;
}
PR_EXC("Current thread ID = %p\n"
printk("Current thread ID = %p\n"
"Faulting instruction address = 0x%x\n",
k_current_get(), pEsf->pc);

View file

@ -41,21 +41,28 @@
void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf)
{
ARG_UNUSED(reason);
ARG_UNUSED(pEsf);
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
if (reason == _NANO_ERR_KERNEL_PANIC) {
goto hang_system;
}
if (k_is_in_isr() || _is_thread_essential()) {
printk("Fatal fault in %s! Spinning...\n",
k_is_in_isr() ? "ISR" : "essential thread");
for (;;)
; /* spin forever */
goto hang_system;
}
printk("Fatal fault in thread %p! Aborting.\n", _current);
k_thread_abort(_current);
return;
hang_system:
#else
ARG_UNUSED(reason);
#endif
for (;;) {
k_cpu_idle();
}
#endif
CODE_UNREACHABLE;
}