Notify about debug configuration for exception decoding
This commit is contained in:
@@ -25,16 +25,29 @@ from platformio.commands.device import DeviceMonitorFilter
|
|||||||
# By design, __init__ is called inside miniterm and we can't pass context to it.
|
# By design, __init__ is called inside miniterm and we can't pass context to it.
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
|
|
||||||
|
|
||||||
class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
||||||
NAME = "esp32_exception_decoder"
|
NAME = "esp32_exception_decoder"
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
self.buffer = ""
|
self.buffer = ""
|
||||||
self.backtrace_re = re.compile(r"^Backtrace: ((0x[0-9a-f]+:0x[0-9a-f]+ ?)+)\s*$")
|
self.backtrace_re = re.compile(
|
||||||
|
r"^Backtrace: ((0x[0-9a-f]+:0x[0-9a-f]+ ?)+)\s*$"
|
||||||
|
)
|
||||||
|
|
||||||
self.firmware_path = None
|
self.firmware_path = None
|
||||||
self.addr2line_path = None
|
self.addr2line_path = None
|
||||||
self.enabled = self.setup_paths()
|
self.enabled = self.setup_paths()
|
||||||
|
|
||||||
|
if self.config.get("env:" + self.environment, "build_type") != "debug":
|
||||||
|
print(
|
||||||
|
"""
|
||||||
|
Please build project in debug configuration to get more details about an exception.
|
||||||
|
See https://docs.platformio.org/page/projectconf/build_configurations.html
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def setup_paths(self):
|
def setup_paths(self):
|
||||||
@@ -43,8 +56,10 @@ class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
|||||||
data = load_project_ide_data(self.project_dir, self.environment)
|
data = load_project_ide_data(self.project_dir, self.environment)
|
||||||
self.firmware_path = data["prog_path"]
|
self.firmware_path = data["prog_path"]
|
||||||
if not os.path.isfile(self.firmware_path):
|
if not os.path.isfile(self.firmware_path):
|
||||||
sys.stderr.write("%s: firmware at %s does not exist, rebuild the project?\n" %
|
sys.stderr.write(
|
||||||
(self.__class__.__name__, self.firmware_path))
|
"%s: firmware at %s does not exist, rebuild the project?\n"
|
||||||
|
% (self.__class__.__name__, self.firmware_path)
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
cc_path = data.get("cc_path", "")
|
cc_path = data.get("cc_path", "")
|
||||||
@@ -54,10 +69,14 @@ class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
|||||||
self.addr2line_path = path
|
self.addr2line_path = path
|
||||||
return True
|
return True
|
||||||
except PlatformioException as e:
|
except PlatformioException as e:
|
||||||
sys.stderr.write("%s: disabling, exception while looking for addr2line: %s\n" %
|
sys.stderr.write(
|
||||||
(self.__class__.__name__, e))
|
"%s: disabling, exception while looking for addr2line: %s\n"
|
||||||
|
% (self.__class__.__name__, e)
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
sys.stderr.write("%s: disabling, failed to find addr2line.\n" % self.__class__.__name__)
|
sys.stderr.write(
|
||||||
|
"%s: disabling, failed to find addr2line.\n" % self.__class__.__name__
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def rx(self, text):
|
def rx(self, text):
|
||||||
@@ -76,7 +95,7 @@ class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
|||||||
if self.buffer:
|
if self.buffer:
|
||||||
line = self.buffer + line
|
line = self.buffer + line
|
||||||
self.buffer = ""
|
self.buffer = ""
|
||||||
last = idx+1
|
last = idx + 1
|
||||||
|
|
||||||
m = self.backtrace_re.match(line)
|
m = self.backtrace_re.match(line)
|
||||||
if m is None:
|
if m is None:
|
||||||
@@ -84,24 +103,32 @@ class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
|||||||
|
|
||||||
trace = self.get_backtrace(m)
|
trace = self.get_backtrace(m)
|
||||||
if len(trace) != "":
|
if len(trace) != "":
|
||||||
text = text[:idx+1] + trace + text[idx+1:]
|
text = text[: idx + 1] + trace + text[idx + 1 :]
|
||||||
last += len(trace)
|
last += len(trace)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def get_backtrace(self, match):
|
def get_backtrace(self, match):
|
||||||
trace = ""
|
trace = ""
|
||||||
enc = get_filesystem_encoding()
|
enc = get_filesystem_encoding()
|
||||||
args = ( self.addr2line_path, "-fipC", "-e", self.firmware_path )
|
args = (self.addr2line_path, "-fipC", "-e", self.firmware_path)
|
||||||
args = [ a.encode(enc) for a in args ]
|
args = [a.encode(enc) for a in args]
|
||||||
try:
|
try:
|
||||||
for i, addr in enumerate(match.group(1).split()):
|
for i, addr in enumerate(match.group(1).split()):
|
||||||
output = subprocess.check_output(args + [ addr.encode(enc) ]).decode(enc).strip()
|
output = (
|
||||||
output = output.replace("\n", "\n ") # newlines happen with inlined methods
|
subprocess.check_output(args + [addr.encode(enc)])
|
||||||
|
.decode(enc)
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
output = output.replace(
|
||||||
|
"\n", "\n "
|
||||||
|
) # newlines happen with inlined methods
|
||||||
output = self.strip_project_dir(output)
|
output = self.strip_project_dir(output)
|
||||||
trace += " #%-2d %s in %s\n" % (i, addr, output)
|
trace += " #%-2d %s in %s\n" % (i, addr, output)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
sys.stderr.write("%s: failed to call %s: %s\n" %
|
sys.stderr.write(
|
||||||
(self.__class__.__name__, self.addr2line_path, e))
|
"%s: failed to call %s: %s\n"
|
||||||
|
% (self.__class__.__name__, self.addr2line_path, e)
|
||||||
|
)
|
||||||
return trace
|
return trace
|
||||||
|
|
||||||
def strip_project_dir(self, trace):
|
def strip_project_dir(self, trace):
|
||||||
@@ -109,5 +136,5 @@ class Esp32ExceptionDecoder(DeviceMonitorFilter):
|
|||||||
idx = trace.find(self.project_dir)
|
idx = trace.find(self.project_dir)
|
||||||
if idx == -1:
|
if idx == -1:
|
||||||
break
|
break
|
||||||
trace = trace[:idx] + trace[idx+len(self.project_dir)+1:]
|
trace = trace[:idx] + trace[idx + len(self.project_dir) + 1 :]
|
||||||
return trace
|
return trace
|
||||||
|
|||||||
Reference in New Issue
Block a user