Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid crashes during fault handler #11970

Merged
merged 1 commit into from
Dec 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platform/mbed_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void mbed_error_vprintf(const char *format, va_list arg) MBED_PRINTF(1, 0);
* FileHandle::write of the stderr device is. The default
* serial console is safe, either buffered or not. If the
* console has not previously been initialized, an attempt
* to use this from interrupt may during console initialization.
* to use this from interrupt may crash during console initialization.
* Special handling of `mbed_error` relaxes various system traps
* to increase the chance of initialization working.
*
Expand Down
65 changes: 37 additions & 28 deletions platform/source/TARGET_CORTEX_M/mbed_fault_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <string.h>

#include "device.h"
#include "mbed_atomic.h"
#include "mbed_error.h"
#include "mbed_interface.h"
#include "mbed_crash_data_offsets.h"
Expand All @@ -39,41 +40,49 @@ mbed_fault_context_t fault_context;
mbed_fault_context_t *const mbed_fault_context = &fault_context;
#endif

extern bool mbed_error_in_progress;

//This is a handler function called from Fault handler to print the error information out.
//This runs in fault context and uses special functions(defined in mbed_rtx_fault_handler.c) to print the information without using C-lib support.
void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in)
{
mbed_error_status_t faultStatus = MBED_SUCCESS;

mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: ");

switch (fault_type) {
case MEMMANAGE_FAULT_EXCEPTION:
mbed_error_printf("MemManageFault");
faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION;
break;

case BUS_FAULT_EXCEPTION:
mbed_error_printf("BusFault");
faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION;
break;

case USAGE_FAULT_EXCEPTION:
mbed_error_printf("UsageFault");
faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION;
break;

//There is no way we can hit this code without getting an exception, so we have the default treated like hardfault
case HARD_FAULT_EXCEPTION:
default:
mbed_error_printf("HardFault");
faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION;
break;
}
mbed_error_printf("\n\nContext:");
print_context_info();
/* Need to set the flag to ensure prints do not trigger a "mutex in ISR" trap
* if they're first prints since boot and we have to init the I/O system.
*/
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: ");

switch (fault_type) {
case MEMMANAGE_FAULT_EXCEPTION:
mbed_error_printf("MemManageFault");
faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION;
break;

case BUS_FAULT_EXCEPTION:
mbed_error_printf("BusFault");
faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION;
break;

case USAGE_FAULT_EXCEPTION:
mbed_error_printf("UsageFault");
faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION;
break;

//There is no way we can hit this code without getting an exception, so we have the default treated like hardfault
case HARD_FAULT_EXCEPTION:
default:
mbed_error_printf("HardFault");
faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION;
break;
}
mbed_error_printf("\n\nContext:");
print_context_info();

mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n");
mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n");
core_util_atomic_store_bool(&mbed_error_in_progress, false);
}

//Now call mbed_error, to log the error and halt the system
mbed_error(faultStatus, "Fault exception", (unsigned int)mbed_fault_context_in, NULL, 0);
Expand Down
8 changes: 4 additions & 4 deletions platform/source/mbed_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *, const ch
#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0)
#endif

static bool error_in_progress;
bool mbed_error_in_progress;
static core_util_atomic_flag halt_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT;
static int error_count = 0;
static mbed_error_ctx first_error_ctx = {0};
Expand Down Expand Up @@ -121,7 +121,7 @@ static MBED_NORETURN void mbed_halt_system(void)
WEAK MBED_NORETURN void error(const char *format, ...)
{
// Prevent recursion if error is called again during store+print attempt
if (!core_util_atomic_exchange_bool(&error_in_progress, true)) {
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR());
ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0);

Expand Down Expand Up @@ -298,7 +298,7 @@ int mbed_get_error_count(void)
//Reads the fatal error occurred" flag
bool mbed_get_error_in_progress(void)
{
return core_util_atomic_load_bool(&error_in_progress);
return core_util_atomic_load_bool(&mbed_error_in_progress);
}

//Sets a non-fatal error
Expand All @@ -311,7 +311,7 @@ mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *e
WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
{
// Prevent recursion if error is called again during store+print attempt
if (!core_util_atomic_exchange_bool(&error_in_progress, true)) {
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
//set the error reported
(void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR());

Expand Down