Crash backtrace analysis for Arduino IDE/ESP32

If you're got your Arduino ESP32 sketch crashing with a message similar to this:

Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
...
Backtrace: 0x400d2606:0x3ffc91e0 0x400d334b:0x3ffc9200 0x400d354f:0x3ffc92a0 0x400d40bb:0x3ffc9330 0x400887a1:0x3ffc9b50
Rebooting...

Notice the Backtrace: BACKTRACE_ADDRESSES line? It points to the place where the crash has happened. That line is not human-readable. It must be symbolised and converted into the file name/line number list. This is a helper script for MacOS that does that:

#!/bin/sh

INO=$1
shift
test -z "$INO" && echo "Usage: $0 SKETCH_NAME addr1 addr2 ..." && exit 1

A2LINE=$(find $HOME/Library/Arduino15 -name xtensa-esp32-elf-addr2line) 
ELF=$(find /var/folders/ -name $INO.ino.elf 2>/dev/null)

$A2LINE  -pfiaC -e $ELF $*

This is how this script works:

  1. It finds a file SKETCH_NAME.ino.elf, which is generated by Arduino IDE during sketch compilation. It is usually located in some temporary files folder.
  2. It finds an executable program called xtensa-esp32-elf-addr2line which was installed during the ESP32 board setup in your Arduino IDE.
  3. Runs xtensa-esp32-elf-addr2line -pfiaC -e FOUND_ELF_FILE ADDRESSES. For every address, that command finds a corresponding source code line using the .elf file, and prints a message.

Run a script like this:

$ sh bt.sh SKETCH_NAME BACKTRACE_ADDRESSES

The SKETCH_NAME should be without the .ino extension. Example run:

$ sh ~/bin/bt.sh sketch_huzzah32 0x400d2606:0x3ffc91e0 0x400d334b:0x3ffc9200 0x400d354f:0x3ffc92a0 0x400d40bb:0x3ffc9330 0x400887a1:0x3ffc9b50

0x400d334b: fsput at /Users/lsm/src/alib/rpc.c:233
0x400d354f: jsonrpc_ctx_process at /Users/lsm/src/alib/mjson.c:869
0x400d40bb: onMessage at /Users/lsm/src/alib/mDash.c:129
 (inlined by) mDashTask at /Users/lsm/src/alib/mDash.c:235