5/02/2021

ESP32 Backtrace 와 addr2line

1. ESP32의 Monitor 기능 

esp32 개발환경에서 제공해주는 idf.py -p /dev/ttyUSBx monitor , 즉 monitor 기능은 기본적으로 gdb option을 포함하고 있다. 
그래서, abort 시 backtrace가 가능한데, 이때 사용하는 기능이 addr2line 기능이며, 이는 각 Stack의 Address를 Code의 위치를 찾는다. 
기본기능으로 아래와 같이 addr2line을 이용하여 위치를 찾아주며, 이 정보는 stderr로 표시해주고 있다. 

  • ESP32가 Exception 이 발생할때 아래와 같이 Dump와 Backtrace 정보출력   
Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90

  • addr2line이용하여 추적가능 
Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
0x400dbf56: still_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:47
0x400dbf5e: dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:42
0x400dbf82: app_main at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:33
0x400d071d: main_task at /home/gus/esp/32/idf/components/esp32/./cpu_start.c:254 

Backtrace는 2개의 Address로 구성되며, PC와 A1, 즉 , Arg라고 짐작 (세부내용은 ABI 참조해야함)

  • addr2line 이용하여 소스위치확인
$ xtensa-esp32-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS  // 상위 Address 입력하면 각 소스위치파악 


  • ESP32 Exception이 발생할 경우 순서도 


GDB-Stub 사용

ESP32 Exception, Fatal Errors

monitor 관련내용

ESP32용 Backtrace Shell Script 


1.1 backtrace 와 addr2line 기본사용법 

backtrace는 Stack Trace라고도 하며, 기본적으로 함수의 Call Stack을 추적하는 방법을 말하며, 주로 사용되어지는 함수가 backtrace기능이다. 
이때 보조적으로 Code의 위치를 찾아주는 기능이 addr2line tool 이며, 이를 이용하여 쉽게 어디서 호출되어지는 분석이 가능하다. 

  • 기본설정 
GCC 로 Compile 시 반드시 -g 옵션 과 -rdynamic (동적 Library)

  • backtrace 함수와 addr2line 사용법 


1.2 addr2line 이용

ESP32는 기존의 Backtrace처럼 사용하지 않는 구조로 보이며, Backtrace가 아래와 같이 나오면 addr2line을 이용하여 쉽게 Source 위치 파악은 가능하다  

Backtrace:0x40090677:0x3ffe3710 0x40090c89:0x3ffe3730 0x400955fa:0x3ffe3750 0x400da8f2:0x3ffe37c0 0x400da9f0:0x3ffe37e0 0x400ec484:0x3ffe3800 0x400ec516:0x3ffe3840 0x400ec651:0x3ffe3870 0x400ec6e4:0x3ffe38a0 0x400daa13:0x3ffe38c0 0x400db275:0x3ffe38f0 0x400db4fa:0x3ffe3920 0x400d8deb:0x3ffe3a70 0x400d978c:0x3ffe3a90 0x40090cf9:0x3ffe3ac0 

$ xtensa-esp32-elf-addr2line 0x40090677 -e ./build/demos  
$ xtensa-esp32-elf-addr2line 0x40090c89 -e ./build/demos 

1.3 이외 Tool 사용 

  • Linux Kernel 처럼 map 분석 
Symbol Table 과 Linker Script Section 과 Library 비롯하여 모든 기본정보 확인
$ cat ./build/demos.map    
// Discarded input sections     (Linker Scirpt 의 Section 과 상대주소 파악 ) 
// Memory Configuration         (실제 Memory 영역과 Attribute로 x/r/w 확인 ) 
// Linker script and memory map (Linker Scirpt 와 같이 절대주소 파악 )
// Cross Reference Table        (Symbol Table로 Symbol의 사용여부 확인가능)

  • readelf 로 Library 분석 및 ELF 분석 
각 Library 및 ELF Format 관련정보 확인 
$ xtensa-esp32-elf-readelf -a ./build/esp-idf/app_trace/libapp_trace.a    //Build 내에서 사용하는 ESP-IDF Library 분석 (-a 전체정보)  
$ xtensa-esp32-elf-readelf -h ./build/esp-idf/app_trace/libapp_trace.a                           //ELF 기본정보확인 (Endian/Entry Point/Machine)   
$ xtensa-esp32-elf-readelf -s ./build/esp-idf/app_trace/libapp_trace.a | grep function           //library Symbol Table 확인   
$ xtensa-esp32-elf-readelf -S ./build/demo                          //Linker Script Section 확인