Skip to content

Commit

Permalink
Merge branch 'coredump-info-offset_v4.4' into 'release/v4.4'
Browse files Browse the repository at this point in the history
Tools: coredump-info - fix non-default partition table offset issues (v4.4)

See merge request espressif/esp-idf!26925
  • Loading branch information
dobairoland committed Nov 14, 2023
2 parents 25cd984 + 9d4d612 commit 4ef8121
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
11 changes: 7 additions & 4 deletions components/espcoredump/corefile/loader.py
Expand Up @@ -439,11 +439,12 @@ def _extract_bin_corefile(self, e_machine=ESPCoreDumpElfFile.EM_XTENSA): # type
class ESPCoreDumpFlashLoader(EspCoreDumpLoader):
ESP_COREDUMP_PART_TABLE_OFF = 0x8000

def __init__(self, offset, target=None, port=None, baud=None):
# type: (int, Optional[str], Optional[str], Optional[int]) -> None
def __init__(self, offset, target=None, port=None, baud=None, part_table_offset=None):
# type: (int, Optional[str], Optional[str], Optional[int], Optional[int]) -> None
super(ESPCoreDumpFlashLoader, self).__init__()
self.port = port
self.baud = baud
self.part_table_offset = part_table_offset

self._get_core_src(offset, target)
self.target = self._load_core_src()
Expand Down Expand Up @@ -521,12 +522,15 @@ def _invoke_parttool(self): # type: () -> None
tool_args = [sys.executable, PARTTOOL_PY]
if 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'])

self.core_src_file = self._create_temp_file()
try:
tool_args.append(self.core_src_file) # type: ignore
# read core dump partition
print(f"Running {' '.join(tool_args)}")
et_out = subprocess.check_output(tool_args)
if et_out:
logging.info(et_out.decode('utf-8'))
Expand All @@ -542,8 +546,7 @@ def _get_core_dump_partition_info(self, part_off=None): # type: (Optional[int])
Get core dump partition info using parttool
"""
logging.info('Retrieving core dump partition offset and size...')
if not part_off:
part_off = self.ESP_COREDUMP_PART_TABLE_OFF
part_off = part_off or self.part_table_offset or self.ESP_COREDUMP_PART_TABLE_OFF
try:
tool_args = [sys.executable, PARTTOOL_PY, '-q', '--partition-table-offset', str(part_off)]
if self.port:
Expand Down
47 changes: 45 additions & 2 deletions components/espcoredump/espcoredump.py
Expand Up @@ -3,11 +3,14 @@
# ESP-IDF Core Dump Utility

import argparse
import json
import logging
import os
import re
import subprocess
import sys
from shutil import copyfile
from typing import Any, List

import serial
from construct import GreedyRange, Int32ul, Struct
Expand Down Expand Up @@ -54,6 +57,39 @@ def load_aux_elf(elf_path): # type: (str) -> str
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):
# type: (int) -> Tuple[str, Optional[str], Optional[list[str]]]
loader = None
Expand All @@ -63,7 +99,10 @@ def get_core_dump_elf(e_machine=ESPCoreDumpFileLoader.ESP32):

if not args.core:
# 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':
# 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')
Expand Down Expand Up @@ -381,7 +420,11 @@ def info_corefile(): # type: () -> Optional[list[str]]
logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)

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:
if args.operation == 'info_corefile':
temp_core_files = info_corefile()
Expand Down

0 comments on commit 4ef8121

Please sign in to comment.