mirror of
https://github.com/esphome/esphome.git
synced 2025-10-25 13:13:48 +01:00
esp32 only platforms
This commit is contained in:
@@ -27,6 +27,12 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# GCC global constructor/destructor prefix annotations
|
||||||
|
_GCC_PREFIX_ANNOTATIONS = {
|
||||||
|
"_GLOBAL__sub_I_": "global constructor for",
|
||||||
|
"_GLOBAL__sub_D_": "global destructor for",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MemorySection:
|
class MemorySection:
|
||||||
@@ -340,33 +346,58 @@ class MemoryAnalyzer:
|
|||||||
text=True,
|
text=True,
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
if result.returncode == 0:
|
except (subprocess.SubprocessError, OSError, UnicodeDecodeError) as e:
|
||||||
demangled_lines = result.stdout.strip().split("\n")
|
# On error, cache originals
|
||||||
# Map original to demangled names
|
_LOGGER.warning("Failed to batch demangle symbols: %s", e)
|
||||||
|
for symbol in symbols:
|
||||||
|
self._demangle_cache[symbol] = symbol
|
||||||
|
return
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"c++filt exited with code %d: %s",
|
||||||
|
result.returncode,
|
||||||
|
result.stderr[:200] if result.stderr else "(no error output)",
|
||||||
|
)
|
||||||
|
# Cache originals on failure
|
||||||
|
for symbol in symbols:
|
||||||
|
self._demangle_cache[symbol] = symbol
|
||||||
|
return
|
||||||
|
|
||||||
|
# Process demangled output
|
||||||
|
self._process_demangled_output(
|
||||||
|
symbols, symbols_stripped, symbols_prefixes, result.stdout, cppfilt_cmd
|
||||||
|
)
|
||||||
|
|
||||||
|
def _process_demangled_output(
|
||||||
|
self,
|
||||||
|
symbols: list[str],
|
||||||
|
symbols_stripped: list[str],
|
||||||
|
symbols_prefixes: list[str],
|
||||||
|
demangled_output: str,
|
||||||
|
cppfilt_cmd: str,
|
||||||
|
) -> None:
|
||||||
|
"""Process demangled symbol output and populate cache.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
symbols: Original symbol names
|
||||||
|
symbols_stripped: Stripped symbol names sent to c++filt
|
||||||
|
symbols_prefixes: Removed prefixes to restore
|
||||||
|
demangled_output: Output from c++filt
|
||||||
|
cppfilt_cmd: Path to c++filt command (for logging)
|
||||||
|
"""
|
||||||
|
demangled_lines = demangled_output.strip().split("\n")
|
||||||
failed_count = 0
|
failed_count = 0
|
||||||
|
|
||||||
for original, stripped, prefix, demangled in zip(
|
for original, stripped, prefix, demangled in zip(
|
||||||
symbols, symbols_stripped, symbols_prefixes, demangled_lines
|
symbols, symbols_stripped, symbols_prefixes, demangled_lines
|
||||||
):
|
):
|
||||||
# Add back any prefix that was removed
|
# Add back any prefix that was removed
|
||||||
if prefix:
|
demangled = self._restore_symbol_prefix(prefix, stripped, demangled)
|
||||||
if demangled != stripped:
|
|
||||||
# Successfully demangled - add descriptive prefix
|
|
||||||
if prefix == "_GLOBAL__sub_I_":
|
|
||||||
demangled = f"[global constructor for: {demangled}]"
|
|
||||||
elif prefix == "_GLOBAL__sub_D_":
|
|
||||||
demangled = f"[global destructor for: {demangled}]"
|
|
||||||
else:
|
|
||||||
# Failed to demangle - restore original prefix
|
|
||||||
demangled = prefix + demangled
|
|
||||||
|
|
||||||
# If we stripped a suffix, add it back to the demangled name for clarity
|
# If we stripped a suffix, add it back to the demangled name for clarity
|
||||||
if original != stripped and not prefix:
|
if original != stripped and not prefix:
|
||||||
# Find what was stripped
|
demangled = self._restore_symbol_suffix(original, demangled)
|
||||||
suffix_match = re.search(
|
|
||||||
r"(\$(?:isra|part|constprop)\$\d+)", original
|
|
||||||
)
|
|
||||||
if suffix_match:
|
|
||||||
demangled = f"{demangled} [{suffix_match.group(1)}]"
|
|
||||||
|
|
||||||
self._demangle_cache[original] = demangled
|
self._demangle_cache[original] = demangled
|
||||||
|
|
||||||
@@ -384,22 +415,47 @@ class MemoryAnalyzer:
|
|||||||
cppfilt_cmd,
|
cppfilt_cmd,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning("Successfully demangled all %d symbols", len(symbols))
|
||||||
"Successfully demangled all %d symbols", len(symbols)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
_LOGGER.warning(
|
|
||||||
"c++filt exited with code %d: %s",
|
|
||||||
result.returncode,
|
|
||||||
result.stderr[:200] if result.stderr else "(no error output)",
|
|
||||||
)
|
|
||||||
except (subprocess.SubprocessError, OSError, UnicodeDecodeError) as e:
|
|
||||||
# On error, cache originals
|
|
||||||
_LOGGER.warning("Failed to batch demangle symbols: %s", e)
|
|
||||||
|
|
||||||
# If demangling failed, cache originals
|
@staticmethod
|
||||||
for symbol in symbols:
|
def _restore_symbol_prefix(prefix: str, stripped: str, demangled: str) -> str:
|
||||||
self._demangle_cache[symbol] = symbol
|
"""Restore prefix that was removed before demangling.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
prefix: Prefix that was removed (e.g., "_GLOBAL__sub_I_")
|
||||||
|
stripped: Stripped symbol name
|
||||||
|
demangled: Demangled symbol name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Demangled name with prefix restored/annotated
|
||||||
|
"""
|
||||||
|
if not prefix:
|
||||||
|
return demangled
|
||||||
|
|
||||||
|
# Successfully demangled - add descriptive prefix
|
||||||
|
if demangled != stripped and (
|
||||||
|
annotation := _GCC_PREFIX_ANNOTATIONS.get(prefix)
|
||||||
|
):
|
||||||
|
return f"[{annotation}: {demangled}]"
|
||||||
|
|
||||||
|
# Failed to demangle - restore original prefix
|
||||||
|
return prefix + demangled
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _restore_symbol_suffix(original: str, demangled: str) -> str:
|
||||||
|
"""Restore GCC optimization suffix that was removed before demangling.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
original: Original symbol name with suffix
|
||||||
|
demangled: Demangled symbol name without suffix
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Demangled name with suffix annotation
|
||||||
|
"""
|
||||||
|
suffix_match = re.search(r"(\$(?:isra|part|constprop)\$\d+)", original)
|
||||||
|
if suffix_match:
|
||||||
|
return f"{demangled} [{suffix_match.group(1)}]"
|
||||||
|
return demangled
|
||||||
|
|
||||||
def _demangle_symbol(self, symbol: str) -> str:
|
def _demangle_symbol(self, symbol: str) -> str:
|
||||||
"""Get demangled C++ symbol name from cache."""
|
"""Get demangled C++ symbol name from cache."""
|
||||||
|
|||||||
Reference in New Issue
Block a user