Summary
firmware_symbolizer.py
that comes with the Playdate SDK ($PLAYDATE_SDK_PATH/bin/firmware_symbolizer.py
) has two issues that are nice to be addressed:
Issue 1
The command that this script calls doesn't wrap the arguments to be passed to arm-none-eabi-addr2line
, causing a file not found
error when trying to decode the crash log.
Issue 2
On Windows, this script crashes because The system cannot find the path specified.
This is because the path to the tool is hardcoded.
Repro steps
- Make Playdate (PD) crash (preferably with e0) one way or another.
- Put PD into data disk mode.
- Extract crashlog.txt.
- Set up
firmware_symbolizer.py
.$ pip3 install click
- Place your ELF symbol file to a path that contains a whitespace (
0x20
). - Try to decode the crash log.
$ python3 firmware_symbolizer.py /path/to/crashlog.txt "/path/to/elf/containing space/game.elf"
Expected behaviour
The script correctly associates the address with the symbol, if possible.
Actual behaviour
If the toolchain exists at the hardcoded path
The script crashes at this line - firmware_symbolizer.py:L34-35:
cmd = f"/usr/local/playdate/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-addr2line -f -i -p -e {elf} 0x{pc} 0x{lr}"
stack = subprocess.check_output(cmd, shell=True).decode('ASCII')
...saying that arm-none-eabi-addr2line
not being able to find /path/to/elf/containing
, instead of the full path to the ELF file.
If the toolchain doesn't exist in an expected path
The script crashes at subprocess.check_output
because the command cannot be found.
Suggested fix
- cmd = f"/usr/local/playdate/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-addr2line -f -i -p -e {elf} 0x{pc} 0x{lr}"
+ cmd = f"arm-none-eabi-addr2line -f -i -p -e \"{elf}\" 0x{pc} 0x{lr}"
stack = subprocess.check_output(cmd, shell=True).decode('ASCII')
- Quote the ELF path.
- Directly call
arm-none-eabi-addr2line
.
Since ARM GCC toolchain should already be in the computer'sPATH
as long as we follow the instruction, we could just call it directly and the script should become OS-agnostic sincesubprocess.check_output
inherits the environment variables present in the terminal session.