@@ -316,3 +316,93 @@ const char * ARDUINO_ISR_ATTR pathToFileName(const char * path)
316
316
return path + pos ;
317
317
}
318
318
319
+ #include "esp_rom_sys.h"
320
+ #include "esp_debug_helpers.h"
321
+ #if CONFIG_IDF_TARGET_ARCH_XTENSA
322
+ #include "esp_cpu_utils.h"
323
+ #else
324
+ #include "riscv/rvruntime-frames.h"
325
+ #endif
326
+ #include "esp_memory_utils.h"
327
+ #include "esp_private/panic_internal.h"
328
+
329
+ static arduino_panic_handler_t _panic_handler = NULL ;
330
+ static void * _panic_handler_arg = NULL ;
331
+
332
+ void set_arduino_panic_handler (arduino_panic_handler_t handler , void * arg ){
333
+ _panic_handler = handler ;
334
+ _panic_handler_arg = arg ;
335
+ }
336
+
337
+ arduino_panic_handler_t * get_arduino_panic_handler (void ){
338
+ return _panic_handler ;
339
+ }
340
+
341
+ void * get_arduino_panic_handler_arg (void ){
342
+ return _panic_handler_arg ;
343
+ }
344
+
345
+ static void handle_custom_backtrace (panic_info_t * info ){
346
+ arduino_panic_info_t p_info ;
347
+ p_info .reason = info -> reason ;
348
+ p_info .core = info -> core ;
349
+ p_info .pc = info -> addr ;
350
+ p_info .backtrace_len = 0 ;
351
+ p_info .backtrace_corrupt = false;
352
+ p_info .backtrace_continues = false;
353
+
354
+ #if CONFIG_IDF_TARGET_ARCH_XTENSA
355
+ XtExcFrame * xt_frame = (XtExcFrame * ) info -> frame ;
356
+ esp_backtrace_frame_t stk_frame = {.pc = xt_frame -> pc , .sp = xt_frame -> a1 , .next_pc = xt_frame -> a0 , .exc_frame = xt_frame };
357
+ uint32_t i = 100 , pc_ptr = esp_cpu_process_stack_pc (stk_frame .pc );
358
+ p_info .backtrace [p_info .backtrace_len ++ ] = pc_ptr ;
359
+
360
+ bool corrupted = !(esp_stack_ptr_is_sane (stk_frame .sp ) &&
361
+ (esp_ptr_executable ((void * )esp_cpu_process_stack_pc (stk_frame .pc )) ||
362
+ /* Ignore the first corrupted PC in case of InstrFetchProhibited */
363
+ (stk_frame .exc_frame && ((XtExcFrame * )stk_frame .exc_frame )-> exccause == EXCCAUSE_INSTR_PROHIBITED )));
364
+
365
+ while (i -- > 0 && stk_frame .next_pc != 0 && !corrupted ) {
366
+ if (!esp_backtrace_get_next_frame (& stk_frame )) {
367
+ corrupted = true;
368
+ }
369
+ pc_ptr = esp_cpu_process_stack_pc (stk_frame .pc );
370
+ if (esp_ptr_executable ((void * )pc_ptr )){
371
+ p_info .backtrace [p_info .backtrace_len ++ ] = pc_ptr ;
372
+ if (p_info .backtrace_len == 60 ){
373
+ break ;
374
+ }
375
+ }
376
+ }
377
+
378
+ if (corrupted ) {
379
+ p_info .backtrace_corrupt = true;
380
+ } else if (stk_frame .next_pc != 0 ) {
381
+ p_info .backtrace_continues = true;
382
+ }
383
+ #elif CONFIG_IDF_TARGET_ARCH_RISCV
384
+ uint32_t sp = (uint32_t )((RvExcFrame * )info -> frame )-> sp ;
385
+ p_info .backtrace [p_info .backtrace_len ++ ] = sp ;
386
+ uint32_t * spptr = (uint32_t * )(sp );
387
+ for (int i = 0 ; i < 256 ; i ++ ){
388
+ if (esp_ptr_executable ((void * )spptr [i ])){
389
+ p_info .backtrace [p_info .backtrace_len ++ ] = spptr [i ];
390
+ if (p_info .backtrace_len == 60 ){
391
+ if (i < 255 ){
392
+ p_info .backtrace_continues = true;
393
+ }
394
+ break ;
395
+ }
396
+ }
397
+ }
398
+ #endif
399
+ _panic_handler (& p_info , _panic_handler_arg );
400
+ }
401
+
402
+ void __real_esp_panic_handler (panic_info_t * );
403
+ void __wrap_esp_panic_handler (panic_info_t * info ) {
404
+ if (_panic_handler != NULL ){
405
+ handle_custom_backtrace (info );
406
+ }
407
+ __real_esp_panic_handler (info );
408
+ }
0 commit comments