From 20c918ce38c25f7e403c2bee668724e5c96d0e48 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Sun, 14 Apr 2024 21:20:48 +0200 Subject: [PATCH] Pio-tools: Exception decoder for remote devices (#21181) --- pio-tools/custom_target.py | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pio-tools/custom_target.py b/pio-tools/custom_target.py index 0ec9bd105..75da53cac 100644 --- a/pio-tools/custom_target.py +++ b/pio-tools/custom_target.py @@ -19,11 +19,14 @@ import os import tasmotapiolib import subprocess import shutil +import json +from colorama import Fore, Back, Style Import("env") platform = env.PioPlatform() board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") +IS_WINDOWS = sys.platform.startswith("win") class FSType(Enum): @@ -287,6 +290,51 @@ def upload_factory(*args, **kwargs): print("Flash firmware at address 0x0") subprocess.call(esptoolpy_cmd, shell=False) +def esp32_use_external_crashreport(*args, **kwargs): + try: + crash_report = env.GetProjectOption("custom_crash_report") + except: + print(Fore.RED + "Did not find custom_crash_report section in the current environment!!") + return + try: + crash_report = json.loads(crash_report) + except: + print(Fore.RED + "No valid JSON, please use output of STATUS 12 in the console!!") + return + print(Fore.GREEN + "Use external crash report (STATUS 12) for debugging:\n", json.dumps(crash_report, sort_keys=True, indent=4)) + epc = crash_report['StatusSTK']['EPC'] + callchain = crash_report['StatusSTK']['CallChain'] + addr2line = "" + for p in platform.get_installed_packages(): + if "toolchain" in p.path: + files = os.listdir(join(p.path,"bin")) + for f in files: + if "addr2line" in f: + addr2line = join(p.path,"bin",f) + elf_file = join(env.subst("$BUILD_DIR"),env.subst("${PROGNAME}.elf")) + if isfile(elf_file) is False: + print(Fore.RED+"Did not find firmware.elf ... please build the current environment first!!") + return + enc = "mbcs" if IS_WINDOWS else "utf-8" + output = ( + subprocess.check_output([addr2line,"-e",elf_file,"-fC","-a",epc]) + .decode(enc) + .strip() + .splitlines() + ) + print(Fore.YELLOW + "There is no way to check, if this data is valid for the given firmware!!") + print(Fore.GREEN + "Crash at:") + print(Fore.YELLOW + output[0] + ": \n" + output[1] + " in " + output[2]) + print(Fore.GREEN + "Callchain:") + for call in callchain: + output = ( + subprocess.check_output([addr2line,"-e",elf_file,"-fC","-a",call]) + .decode(enc) + .strip() + .splitlines() + ) + print(Fore.YELLOW + output[0]+": \n"+output[1]+" in "+output[2]) + env.AddCustomTarget( name="downloadfs", dependencies=None, @@ -306,3 +354,13 @@ env.AddCustomTarget( title="Flash factory", description="Flash factory firmware" ) + +env.AddCustomTarget( + name="external_crashreport", + dependencies=None, + actions=[ + esp32_use_external_crashreport + ], + title="External crash report", + description="Use external crashreport from Tasmotas console output of STATUS 12" +)