When your Arudino sketch is crashing it produces something as follows

13:45:41.992 -> 
13:45:41.992 -> Backtrace: 0x40083585:0x3ffb2690 0x400892ad:0x3ffb26b0 0x4008e2f1:0x3ffb26d0 0x400d1442:0x3ffb2800 0x400d2be1:0x3ffb2820
13:45:41.992 -> 
13:45:41.992 -> 
13:45:41.992 -> 
13:45:41.992 -> 
13:45:41.992 -> ELF file SHA256: 9868280367130d7a

It is vital to be able to analyse this backtrace and translate it to methods and file names. In Arduino we could use the EspExceptionDecoder to do this.

Unfortunately this is not supported by Arduino 2.0! No problem – I thought, so I just continue to use the old Arduino version. But when I moved my work to Linux, this functionality stopped to work as well!

Now I was looking for some easy to use work-around. It turns out we can do this with this python script. I was not very happy with it because of all the necessary parameters so I decided create my own version and to add the following improvements:

  • Provide a global variable to set the toolchain_default path
  • Provide a global variable to set the elf_default path
  • Determine the elf file automatically by using the most recent elf file in the path defined above

The values for the parameters above can be determined from the last entry in the log when you compile your Sketch in Arduino and these values might only change when you install an new esp32 version.

I also did not like that the backtrace needed to be specified in a separate file, so I changed the logic, so that we can specify it directly on the command line.

In order to install this Python script

  1. Download the script to the file esp32-stacktrace
  2. Update the global default variables
  3. Make it executable (e.g. with chmod +x esp32-esp32-stacktrace
  4. Move it to a location on the search path (e.g. usr/bin)

Now you should be ready to use it by typing the following command in the terminal:

esp32-stacktrace "0x40083585:0x3ffb2690 0x400892ad:0x3ffb26b0 0x4008e2f1:0x3ffb26d0 0x400d1442:0x3ffb2800 0x400d2be1:0x3ffb2820"

This gives the following result

elf = /home/pschatzmann/.var/app/cc.arduino.IDE2/cache/arduino-sketch-93C5D26949BAF1CE46343309937C5D93/sketch_jan25a.ino.elf

Stack trace:

     0x40083585:  panic_abort  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c: line 402'
     0x400892ad:  esp_system_abort  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c: line 128'
     0x4008e2f1:  __assert_func  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/assert.c: line 85'
     0x400d1442:  loop()  at /home/pschatzmann/.var/app/cc.arduino.IDE2/cache/.arduinoIDE-unsaved2023025-30-ox4b5b.v436/sketch_jan25a/sketch_jan25a.ino: line 10'
     0x400d2be1:  loopTask(void*)  at /home/pschatzmann/.arduino15/packages/esp32/hardware/esp32/2.0.6/cores/esp32/main.cpp: line 50'

1 Comment

Radek Suski · 14. April 2023 at 15:54

Hi, many thanks for your script. It is EXTREMELY helpful. I noticed however 3 small issues:

In your example you are defining:
toolchain_default = “/home/pschatzmann/….”
But then you are defining:
default=os.path.join(os.environ.get(“HOME”), toolchain_default))

So I assume the toolchain_default should be relative to one’s home directory.

In usage example you are running:
esp32-stacktrace “0x40083585:0x3ffb2690 ….”

But in your code you are searching for the string “Backtrace”:
m = re.search(‘Backtrace: (.*)’, text)

So the usage example should be rather:
esp32-stacktrace “Backtrace: 0x40083585:0x3ffb2690 ….”

And finally, although it can be my own misconfiguration, you are searching for “xtensa-esp32-elf-addr2line” but while using ESP32S3 the file is called: “xtensa-esp32s3-elf-addr2line”

Once again: it shouldn’t be criticism, I am very grateful for your work 🙂

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *