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