From a4246bcfa3b3305fed60732e46451cb3ca1c41b3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 30 Aug 2021 18:05:14 -0700 Subject: [PATCH] Fix two watchdog crashes Fixes a crash from trying to raise an exception when trying to deinit a RESET wdt by not raising an exception. Fixes a crash when raise a wdt exception in the REPL when waiting for input. We now catch and print any exceptions raised. Fixes #5261 --- lib/utils/pyexec.c | 16 +++++++++++++++- locale/circuitpython.pot | 1 + ports/nrf/common-hal/watchdog/WatchDogTimer.c | 7 ++++++- supervisor/shared/bluetooth/file_transfer.c | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index c1bb66aad1..a272eefbcb 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -650,7 +650,21 @@ friendly_repl_reset: } vstr_reset(&line); - int ret = readline(&line, ">>> "); + + nlr_buf_t nlr; + nlr.ret_val = NULL; + int ret = 0; + if (nlr_push(&nlr) == 0) { + ret = readline(&line, ">>> "); + } else { + // Uncaught exception + mp_handle_pending(false); // clear any pending exceptions (and run any callbacks) + + // Print exceptions but stay in the REPL. There are very few delayed + // exceptions. The WatchDogTimer can raise one though. + mp_hal_stdout_tx_str("\r\n"); + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + } mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT; if (ret == CHAR_CTRL_A) { diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a614078beb..12b42cddf7 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -3939,6 +3939,7 @@ msgstr "" #: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h #: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h +#: ports/esp32s2/boards/lolin_s2_mini/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.c b/ports/nrf/common-hal/watchdog/WatchDogTimer.c index 3423d3466b..1798c52609 100644 --- a/ports/nrf/common-hal/watchdog/WatchDogTimer.c +++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -28,6 +28,7 @@ #include #include +#include "py/gc.h" #include "py/obj.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -94,7 +95,11 @@ void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { if (self->mode == WATCHDOGMODE_RESET) { - mp_raise_NotImplementedError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); + if (gc_alloc_possible()) { + mp_raise_NotImplementedError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); + } + // Don't change anything because RESET cannot be undone. + return; } if (timer) { timer_free(); diff --git a/supervisor/shared/bluetooth/file_transfer.c b/supervisor/shared/bluetooth/file_transfer.c index d105892582..908cc958d6 100644 --- a/supervisor/shared/bluetooth/file_transfer.c +++ b/supervisor/shared/bluetooth/file_transfer.c @@ -404,7 +404,7 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) { FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; char *path = (char *)((uint8_t *)command) + header_size; path[command->path_length] = '\0'; - FRESULT result; + FRESULT result = FR_OK; FILINFO file; if (f_stat(fs, path, &file) == FR_OK) { if ((file.fattrib & AM_DIR) != 0) {