Skip to content

Commit 64d172c

Browse files
authored
Merge pull request #11970 from kjbracey-arm/fault_crash
Avoid crashes during fault handler
2 parents bbf68d7 + fc05d51 commit 64d172c

File tree

3 files changed

+42
-33
lines changed

3 files changed

+42
-33
lines changed

platform/mbed_interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void mbed_error_vprintf(const char *format, va_list arg) MBED_PRINTF(1, 0);
168168
* FileHandle::write of the stderr device is. The default
169169
* serial console is safe, either buffered or not. If the
170170
* console has not previously been initialized, an attempt
171-
* to use this from interrupt may during console initialization.
171+
* to use this from interrupt may crash during console initialization.
172172
* Special handling of `mbed_error` relaxes various system traps
173173
* to increase the chance of initialization working.
174174
*

platform/source/TARGET_CORTEX_M/mbed_fault_handler.c

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <string.h>
2222

2323
#include "device.h"
24+
#include "mbed_atomic.h"
2425
#include "mbed_error.h"
2526
#include "mbed_interface.h"
2627
#include "mbed_crash_data_offsets.h"
@@ -39,41 +40,49 @@ mbed_fault_context_t fault_context;
3940
mbed_fault_context_t *const mbed_fault_context = &fault_context;
4041
#endif
4142

43+
extern bool mbed_error_in_progress;
44+
4245
//This is a handler function called from Fault handler to print the error information out.
4346
//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.
4447
void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in)
4548
{
4649
mbed_error_status_t faultStatus = MBED_SUCCESS;
4750

48-
mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: ");
49-
50-
switch (fault_type) {
51-
case MEMMANAGE_FAULT_EXCEPTION:
52-
mbed_error_printf("MemManageFault");
53-
faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION;
54-
break;
55-
56-
case BUS_FAULT_EXCEPTION:
57-
mbed_error_printf("BusFault");
58-
faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION;
59-
break;
60-
61-
case USAGE_FAULT_EXCEPTION:
62-
mbed_error_printf("UsageFault");
63-
faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION;
64-
break;
65-
66-
//There is no way we can hit this code without getting an exception, so we have the default treated like hardfault
67-
case HARD_FAULT_EXCEPTION:
68-
default:
69-
mbed_error_printf("HardFault");
70-
faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION;
71-
break;
72-
}
73-
mbed_error_printf("\n\nContext:");
74-
print_context_info();
51+
/* Need to set the flag to ensure prints do not trigger a "mutex in ISR" trap
52+
* if they're first prints since boot and we have to init the I/O system.
53+
*/
54+
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
55+
mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: ");
56+
57+
switch (fault_type) {
58+
case MEMMANAGE_FAULT_EXCEPTION:
59+
mbed_error_printf("MemManageFault");
60+
faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION;
61+
break;
62+
63+
case BUS_FAULT_EXCEPTION:
64+
mbed_error_printf("BusFault");
65+
faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION;
66+
break;
67+
68+
case USAGE_FAULT_EXCEPTION:
69+
mbed_error_printf("UsageFault");
70+
faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION;
71+
break;
72+
73+
//There is no way we can hit this code without getting an exception, so we have the default treated like hardfault
74+
case HARD_FAULT_EXCEPTION:
75+
default:
76+
mbed_error_printf("HardFault");
77+
faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION;
78+
break;
79+
}
80+
mbed_error_printf("\n\nContext:");
81+
print_context_info();
7582

76-
mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n");
83+
mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n");
84+
core_util_atomic_store_bool(&mbed_error_in_progress, false);
85+
}
7786

7887
//Now call mbed_error, to log the error and halt the system
7988
mbed_error(faultStatus, "Fault exception", (unsigned int)mbed_fault_context_in, NULL, 0);

platform/source/mbed_error.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *, const ch
5252
#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0)
5353
#endif
5454

55-
static bool error_in_progress;
55+
bool mbed_error_in_progress;
5656
static core_util_atomic_flag halt_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT;
5757
static int error_count = 0;
5858
static mbed_error_ctx first_error_ctx = {0};
@@ -92,7 +92,7 @@ static MBED_NORETURN void mbed_halt_system(void)
9292
WEAK MBED_NORETURN void error(const char *format, ...)
9393
{
9494
// Prevent recursion if error is called again during store+print attempt
95-
if (!core_util_atomic_exchange_bool(&error_in_progress, true)) {
95+
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
9696
handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR());
9797
ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0);
9898

@@ -269,7 +269,7 @@ int mbed_get_error_count(void)
269269
//Reads the fatal error occurred" flag
270270
bool mbed_get_error_in_progress(void)
271271
{
272-
return core_util_atomic_load_bool(&error_in_progress);
272+
return core_util_atomic_load_bool(&mbed_error_in_progress);
273273
}
274274

275275
//Sets a non-fatal error
@@ -282,7 +282,7 @@ mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *e
282282
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)
283283
{
284284
// Prevent recursion if error is called again during store+print attempt
285-
if (!core_util_atomic_exchange_bool(&error_in_progress, true)) {
285+
if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) {
286286
//set the error reported
287287
(void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR());
288288

0 commit comments

Comments
 (0)