diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index fe8c004fa..c7beafd37 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -11,10 +11,10 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#ifndef __ESP_ERR_H__ -#define __ESP_ERR_H__ +#pragma once #include +#include #include #ifdef __cplusplus @@ -40,22 +40,38 @@ typedef int32_t esp_err_t; #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ +void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn)); + +#ifndef __ASSERT_FUNC +/* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which + uses /usr/include/assert.h or equivalent. +*/ +#ifdef __ASSERT_FUNCTION +#define __ASSERT_FUNC __ASSERT_FUNCTION /* used in glibc assert.h */ +#else +#define __ASSERT_FUNC "??" +#endif +#endif + /** * Macro which can be used to check the error code, * and terminate the program in case the code is not ESP_OK. - * Prints the failed statement to serial output. + * Prints the error code, error location, and the failed statement to serial output. * - * Note: this macro is not safe to use if flash cache - * may be disabled. + * Disabled if assertions are disabled. */ #ifdef NDEBUG -#define ESP_ERROR_CHECK(x) +#define ESP_ERROR_CHECK(x) do { (x); } while (0) #else -#define ESP_ERROR_CHECK(x) do { esp_err_t rc = (x); if (rc != ESP_OK) { ESP_LOGE("err", "esp_err_t = %d", rc); assert(0 && #x);} } while(0); +#define ESP_ERROR_CHECK(x) do { \ + esp_err_t rc = (x); \ + if (rc != ESP_OK) { \ + _esp_error_check_failed(rc, __FILE__, __LINE__, \ + __ASSERT_FUNC, #x); \ + } \ + } while(0); #endif #ifdef __cplusplus } #endif - -#endif /* __ESP_ERR_H__ */ diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 4f0497d6e..cd426344e 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -34,6 +34,7 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_core_dump.h" +#include "esp_spi_flash.h" /* Panic handlers; these get called when an unhandled exception occurs or the assembly-level @@ -107,11 +108,8 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, s static bool abort_called; -void abort() +static __attribute__((noreturn)) inline void invoke_abort() { -#if !CONFIG_ESP32_PANIC_SILENT_REBOOT - ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3); -#endif abort_called = true; while(1) { __asm__ ("break 0,0"); @@ -119,6 +117,14 @@ void abort() } } +void abort() +{ +#if !CONFIG_ESP32_PANIC_SILENT_REBOOT + ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3); +#endif + invoke_abort(); +} + static const char *edesc[] = { "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", @@ -441,4 +447,11 @@ void esp_clear_watchpoint(int no) } } - +void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) +{ + ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at 0x%08x\n", rc, (intptr_t)__builtin_return_address(0) - 3); + if (spi_flash_cache_enabled()) { // strings may be in flash cache + ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression); + } + invoke_abort(); +} diff --git a/components/nvs_flash/test_nvs_host/Makefile b/components/nvs_flash/test_nvs_host/Makefile index 600621396..133762992 100644 --- a/components/nvs_flash/test_nvs_host/Makefile +++ b/components/nvs_flash/test_nvs_host/Makefile @@ -2,6 +2,7 @@ TEST_PROGRAM=test_nvs all: $(TEST_PROGRAM) SOURCE_FILES = \ + esp_error_check_stub.cpp \ $(addprefix ../src/, \ nvs_types.cpp \ nvs_api.cpp \ diff --git a/components/nvs_flash/test_nvs_host/esp_error_check_stub.cpp b/components/nvs_flash/test_nvs_host/esp_error_check_stub.cpp new file mode 100644 index 000000000..9cff4af31 --- /dev/null +++ b/components/nvs_flash/test_nvs_host/esp_error_check_stub.cpp @@ -0,0 +1,9 @@ +#include "catch.hpp" +#include "esp_err.h" + +void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) +{ + printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at %p\n", rc, __builtin_return_address(0)); + printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression); + abort(); +}