fix(tools/coredump-info): pass non-default partition table offset to esp-coredump

This commit is contained in:
Peter Dragun
2023-11-01 10:27:36 +01:00
parent 8b63bba2e8
commit 9d4d612b56
2 changed files with 52 additions and 6 deletions

View File

@@ -439,11 +439,12 @@ class EspCoreDumpLoader(EspCoreDumpVersion):
class ESPCoreDumpFlashLoader(EspCoreDumpLoader): class ESPCoreDumpFlashLoader(EspCoreDumpLoader):
ESP_COREDUMP_PART_TABLE_OFF = 0x8000 ESP_COREDUMP_PART_TABLE_OFF = 0x8000
def __init__(self, offset, target=None, port=None, baud=None): def __init__(self, offset, target=None, port=None, baud=None, part_table_offset=None):
# type: (int, Optional[str], Optional[str], Optional[int]) -> None # type: (int, Optional[str], Optional[str], Optional[int], Optional[int]) -> None
super(ESPCoreDumpFlashLoader, self).__init__() super(ESPCoreDumpFlashLoader, self).__init__()
self.port = port self.port = port
self.baud = baud self.baud = baud
self.part_table_offset = part_table_offset
self._get_core_src(offset, target) self._get_core_src(offset, target)
self.target = self._load_core_src() self.target = self._load_core_src()
@@ -521,12 +522,15 @@ class ESPCoreDumpFlashLoader(EspCoreDumpLoader):
tool_args = [sys.executable, PARTTOOL_PY] tool_args = [sys.executable, PARTTOOL_PY]
if self.port: if self.port:
tool_args.extend(['--port', self.port]) tool_args.extend(['--port', self.port])
if self.part_table_offset:
tool_args.extend(['--partition-table-offset', str(self.part_table_offset)])
tool_args.extend(['read_partition', '--partition-type', 'data', '--partition-subtype', 'coredump', '--output']) tool_args.extend(['read_partition', '--partition-type', 'data', '--partition-subtype', 'coredump', '--output'])
self.core_src_file = self._create_temp_file() self.core_src_file = self._create_temp_file()
try: try:
tool_args.append(self.core_src_file) # type: ignore tool_args.append(self.core_src_file) # type: ignore
# read core dump partition # read core dump partition
print(f"Running {' '.join(tool_args)}")
et_out = subprocess.check_output(tool_args) et_out = subprocess.check_output(tool_args)
if et_out: if et_out:
logging.info(et_out.decode('utf-8')) logging.info(et_out.decode('utf-8'))
@@ -542,8 +546,7 @@ class ESPCoreDumpFlashLoader(EspCoreDumpLoader):
Get core dump partition info using parttool Get core dump partition info using parttool
""" """
logging.info('Retrieving core dump partition offset and size...') logging.info('Retrieving core dump partition offset and size...')
if not part_off: part_off = part_off or self.part_table_offset or self.ESP_COREDUMP_PART_TABLE_OFF
part_off = self.ESP_COREDUMP_PART_TABLE_OFF
try: try:
tool_args = [sys.executable, PARTTOOL_PY, '-q', '--partition-table-offset', str(part_off)] tool_args = [sys.executable, PARTTOOL_PY, '-q', '--partition-table-offset', str(part_off)]
if self.port: if self.port:

View File

@@ -3,11 +3,14 @@
# ESP-IDF Core Dump Utility # ESP-IDF Core Dump Utility
import argparse import argparse
import json
import logging import logging
import os import os
import re
import subprocess import subprocess
import sys import sys
from shutil import copyfile from shutil import copyfile
from typing import Any, List
import serial import serial
from construct import GreedyRange, Int32ul, Struct from construct import GreedyRange, Int32ul, Struct
@@ -54,6 +57,39 @@ def load_aux_elf(elf_path): # type: (str) -> str
return sym_cmd return sym_cmd
def get_sdkconfig_value(sdkconfig_file, key): # type: (str, str) -> Optional[str]
"""
Return the value of given key from sdkconfig_file.
If sdkconfig_file does not exist or the option is not present, returns None.
"""
assert key.startswith('CONFIG_')
if not os.path.exists(sdkconfig_file):
return None
# keep track of the last seen value for the given key
value = None
# if the value is quoted, this excludes the quotes from the value
pattern = re.compile(r"^{}=\"?([^\"]*)\"?$".format(key))
with open(sdkconfig_file, 'r') as f:
for line in f:
match = re.match(pattern, line)
if match:
value = match.group(1)
return value
def get_project_desc(prog_path): # type: (str) -> Any
build_dir = os.path.abspath(os.path.dirname(prog_path))
desc_path = os.path.abspath(os.path.join(build_dir, 'project_description.json'))
if not os.path.isfile(desc_path):
logging.warning('%s does not exist. Please build the app with "idf.py build"', desc_path)
return ''
with open(desc_path, 'r') as f:
project_desc = json.load(f)
return project_desc
def get_core_dump_elf(e_machine=ESPCoreDumpFileLoader.ESP32): def get_core_dump_elf(e_machine=ESPCoreDumpFileLoader.ESP32):
# type: (int) -> Tuple[str, Optional[str], Optional[list[str]]] # type: (int) -> Tuple[str, Optional[str], Optional[list[str]]]
loader = None loader = None
@@ -63,7 +99,10 @@ def get_core_dump_elf(e_machine=ESPCoreDumpFileLoader.ESP32):
if not args.core: if not args.core:
# Core file not specified, try to read core dump from flash. # Core file not specified, try to read core dump from flash.
loader = ESPCoreDumpFlashLoader(args.off, args.chip, port=args.port, baud=args.baud) loader = ESPCoreDumpFlashLoader(
args.off, args.chip, port=args.port, baud=args.baud,
part_table_offset=getattr(args, 'parttable_off', None)
)
elif args.core_format != 'elf': elif args.core_format != 'elf':
# Core file specified, but not yet in ELF format. Convert it from raw or base64 into ELF. # Core file specified, but not yet in ELF format. Convert it from raw or base64 into ELF.
loader = ESPCoreDumpFileLoader(args.core, args.core_format == 'b64') loader = ESPCoreDumpFileLoader(args.core, args.core_format == 'b64')
@@ -381,7 +420,11 @@ if __name__ == '__main__':
logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level) logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)
print('espcoredump.py v%s' % __version__) print('espcoredump.py v%s' % __version__)
temp_core_files = None project_desc = get_project_desc(args.prog)
if project_desc:
setattr(args, 'parttable_off', get_sdkconfig_value(project_desc['config_file'], 'CONFIG_PARTITION_TABLE_OFFSET'))
temp_core_files = [] # type: Optional[List[str]]
try: try:
if args.operation == 'info_corefile': if args.operation == 'info_corefile':
temp_core_files = info_corefile() temp_core_files = info_corefile()