Address Copilot review: per-line stacktrace + alignment-safe read

- Split text into lines before calling process_stacktrace in client.py,
  since process_stacktrace uses re.match and expects individual lines.
- Use memcpy instead of direct pointer cast for reading the instruction
  before a return address, since RISC-V C extension means code addresses
  are only 2-byte aligned and addr-4 may not be 4-byte aligned.

Co-Authored-By: J. Nick Koston <nick@koston.org>
This commit is contained in:
J. Nick Koston
2026-03-11 12:00:36 -10:00
co-authored by J. Nick Koston
parent 9bcf6adaed
commit 8eea2ce7ca
2 changed files with 14 additions and 7 deletions
+9 -6
View File
@@ -79,12 +79,15 @@ async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None:
)
for parsed_msg in parse_log_message(text, timestamp):
print(parsed_msg.replace("\033", "\\033") if dashboard else parsed_msg)
if platform_process_stacktrace:
backtrace_state = platform_process_stacktrace(config, text, backtrace_state)
else:
backtrace_state = process_stacktrace(
config, text, backtrace_state=backtrace_state
)
for raw_line in text.splitlines():
if platform_process_stacktrace:
backtrace_state = platform_process_stacktrace(
config, raw_line, backtrace_state
)
else:
backtrace_state = process_stacktrace(
config, raw_line, backtrace_state=backtrace_state
)
stop = await async_run(cli, on_log, name=name)
try:
+5 -1
View File
@@ -4,6 +4,7 @@
#include "esphome/core/log.h"
#include <cinttypes>
#include <cstring>
#include <esp_attr.h>
#include <esp_private/panic_internal.h>
#include <soc/soc.h>
@@ -34,7 +35,10 @@ static inline bool is_return_addr(uint32_t addr) {
return false;
// A return address on the stack points to the instruction after a call.
// Check for 4-byte JAL/JALR call instruction before this address.
uint32_t inst = *(uint32_t *) (addr - 4);
// Use memcpy for alignment safety — RISC-V C extension means code addresses
// are only 2-byte aligned, so addr-4 may not be 4-byte aligned.
uint32_t inst;
memcpy(&inst, (const void *) (addr - 4), sizeof(inst));
// RISC-V instruction encoding: bits [6:0] = opcode, bits [11:7] = rd
uint32_t opcode = inst & 0x7f; // Extract 7-bit opcode
uint32_t rd = inst & 0xf80; // Extract rd field (bits 11:7)