Commit Graph
24530 Commits
Author SHA1 Message Date
J. Nick Koston 2f03fbf53f Merge branch 'esp32-crash-handler' into integration 2026-03-11 14:07:38 -10:00
J. Nick KostonandJ. Nick Koston 42ac8c705a Guard crash handler behind USE_ESP32_CRASH_HANDLER define
Arduino framework already wraps esp_panic_handler for its own
backtrace handler, causing a linker conflict. Only enable our
crash handler when using ESP-IDF framework by gating behind
USE_ESP32_CRASH_HANDLER define (set via cg.add_define).

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 14:02:28 -10:00
J. Nick Koston a5dffabe6e Merge branch 'esp32-crash-handler' into integration 2026-03-11 13:02:34 -10:00
J. Nick KostonandJ. Nick Koston 35801d795a Fix missed rename: reason[0] -> REASON[0] in sizeof expressions
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 12:39:55 -10:00
J. Nick KostonandJ. Nick Koston 147eae4b36 Fix clang-tidy: UPPER_SNAKE_CASE for static local constants
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 12:37:49 -10:00
J. Nick KostonandJ. Nick Koston 7e484d16ee Keep CRASH_DATA_VERSION at 1 since version 1 was never shipped
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 12:29:19 -10:00
J. Nick KostonandJ. Nick Koston 1b438b2514 Log exception cause reason in crash report
Store the exception cause register (exccause/mcause) and exception
type (panic_exception_t) in the .noinit struct. At log time, look up
the cause code in architecture-specific tables mirroring ESP-IDF's
internal panic_arch_fill_info() arrays.

Output now shows e.g.:
  Reason: Fault - Store access fault       (RISC-V)
  Reason: Fault - StoreProhibited          (Xtensa)
  Reason: Interrupt wdt                    (watchdog, type-only)

Bumps CRASH_DATA_VERSION to 2. Struct gains +4 bytes (cause field)
with no padding increase (exception and pseudo_excause fit in existing
padding alongside backtrace_count and reg_frame_count). All fields
are clamped on read to prevent corrupt .noinit data from causing
out-of-bounds array access.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 12:28:35 -10:00
J. Nick KostonandJ. Nick Koston 19c3187bb5 Distinguish trusted vs stack-scanned frames in RISC-V output
On RISC-V, register-sourced entries (MEPC/RA) are labeled
"backtrace" while stack-scanned entries are labeled "stack scan"
to help users identify which frames are most trustworthy.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 12:06:18 -10:00
J. Nick KostonandJ. Nick Koston 8eea2ce7ca 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>
2026-03-11 12:00:36 -10:00
J. Nick KostonandJ. Nick Koston 9bcf6adaed Improve RISC-V return address validation
- Add compressed c.jalr (2-byte) instruction check alongside 4-byte
  JAL/JALR, since ESP32 RISC-V targets have the C extension enabled.
- Track register-sourced entries (MEPC/RA) separately from stack-scanned
  ones, and skip return-address validation for register entries since
  they are known-good values from the exception frame.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:57:54 -10:00
J. Nick KostonandJ. Nick Koston b1317939da Fix clang-tidy errors: NOLINT for mutable globals and linker symbols
- s_raw_crash_data and s_crash_data_valid must be mutable globals
- __real_/__wrap_ names are mandated by the --wrap linker mechanism

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:43:45 -10:00
J. Nick KostonandJ. Nick Koston 8e37d8c57d Remove misleading serial console hint for RISC-V
IDF doesn't decode RISC-V backtraces on the console either — it just
dumps raw stack memory. Our crash handler provides a better trace.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:41:07 -10:00
J. Nick KostonandJ. Nick Koston b38bcfe466 Add hint for RISC-V users to check serial console for full trace
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:39:52 -10:00
J. Nick KostonandJ. Nick Koston e42a8c5a0c Add comments explaining RISC-V instruction encoding bit masks
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:38:55 -10:00
J. Nick KostonandJ. Nick Koston f3923ff170 Filter RISC-V backtrace by validating return addresses at log time
Stack scanning captures any value that looks like a code address, which
includes false positives. At log time (flash cache is up), validate each
address by checking if the preceding instruction is a JAL/JALR with
rd=ra. This filters spurious entries like FreeRTOS internals that happen
to be on the stack but aren't part of the actual call chain.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:37:57 -10:00
J. Nick KostonandJ. Nick Koston 2e77f5da25 Add comment explaining why version is uint32_t
Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:23:28 -10:00
J. Nick KostonandJ. Nick Koston b08d19bd7e Move version to first field as uint32_t
Version first ensures future firmware can always identify the struct
layout without depending on any other field positions.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:23:00 -10:00
J. Nick KostonandJ. Nick Koston 5e472e8171 Add version field to crash data struct for future extensibility
Allows future firmware to detect and skip incompatible crash data
layouts. Placed alongside backtrace_count to avoid adding padding.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:22:26 -10:00
J. Nick KostonandJ. Nick Koston f2dee1433c Place backtrace_count before array for forward compatibility
Moving backtrace_count before the variable-length backtrace array
ensures magic, pc, and count are at fixed offsets regardless of
MAX_BACKTRACE value. This makes the .noinit data readable across
firmware versions that may change the max backtrace depth.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:21:05 -10:00
J. Nick KostonandJ. Nick Koston f37610bfe1 Eliminate duplicate BSS struct, read directly from .noinit data
Saves 76 bytes of RAM by removing the validated BSS copy and reading
directly from the .noinit struct after magic validation. A single bool
tracks whether valid crash data was found this boot.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-03-11 11:19:40 -10:00
J. Nick Koston 7acf3f77c4 Increase max backtrace depth from 8 to 16
8 frames was cutting off useful call stack information. 16 frames
costs an additional 32 bytes of .noinit RAM and covers typical
ESPHome call chains which can be 10-12 frames deep.
2026-03-11 11:06:15 -10:00
J. Nick Koston 5adae52819 Add stacktrace decoding to API log path
The esphome logs command via API wasn't running process_stacktrace
on received log lines, so crash handler backtrace addresses were
displayed but not decoded with addr2line.
2026-03-11 11:05:52 -10:00
J. Nick Koston a80cc50b8f fix not survive 2026-03-11 10:55:00 -10:00
J. Nick Koston 9f61331187 Address Copilot review: static linkage + keep valid flag
- Make s_raw_crash_data static with inline .noinit definition (no extern needed)
- Remove valid=false clearing from crash_handler_log() so both serial (boot)
  and API (subscribe) paths can emit the crash data
2026-03-11 10:46:49 -10:00
J. Nick Koston 84813ded94 Add test for ESP32 crash handler stacktrace decoding 2026-03-11 10:43:52 -10:00
J. Nick Koston 1c6dd56512 Address review feedback
- Clear valid flag after logging to prevent re-logging on API reconnects
- Cache esp_cpu_process_stack_pc result to avoid redundant call
- Remove unused <cstdint> include from header
2026-03-11 10:38:49 -10:00
J. Nick Koston 3a7a552f0d [esp32] Add crash handler to capture and report backtrace across reboots
When an ESP32 crashes, the backtrace is printed to UART and lost.
Users without a serial cable never see this diagnostic information.

This adds a crash handler that:
- Intercepts esp_panic_handler() via --wrap linker flag
- Captures the faulting PC and backtrace into .noinit memory
- Supports both Xtensa (ESP32/S2/S3) and RISC-V (C3/C6/H2/C2)
- Logs crash data at boot via ESP_LOGE (serial output)
- Re-logs when HA subscribes to logs (visible in HA log viewer)
- Adds CLI stacktrace decoding for the new log format
2026-03-11 10:34:00 -10:00
J. Nick Koston 2e179f2047 Merge branch 'fix-esp8266-settimeofday' into integration 2026-03-11 09:45:34 -10:00
J. Nick Koston 058146a41f Merge branch 'fix-lwip-pcb-use-after-free' into integration 2026-03-11 09:45:30 -10:00
J. Nick Koston a11f3b6971 [socket] Don't call tcp_recv/tcp_err on listen PCBs
tcp_pcb_listen is a smaller struct than tcp_pcb — calling tcp_recv()
or tcp_err() on it writes past the struct boundary. Revert the listen
PCB close to plain tcp_close(), which is synchronous for listen PCBs
(no async callbacks to worry about).
2026-03-11 09:45:02 -10:00
J. Nick Koston d6db522b1d [time] Fix settimeofday() failure on ESP8266
ESP8266's settimeofday() returns EINVAL (22) directly as the return
value when the timezone parameter is non-NULL, rather than following
POSIX convention of returning -1 and setting errno. The previous
fallback code checked errno == EINVAL which never matched because
errno was never set, so the retry with nullptr never triggered.

Fix by always passing nullptr on ESP8266 since the platform requires it.
2026-03-11 09:40:23 -10:00
J. Nick Koston 02af12c465 Merge branch 'fix-lwip-pcb-use-after-free' into integration 2026-03-11 09:31:27 -10:00
dependabot[bot] a060f175ad Bump actions/download-artifact from 8.0.0 to 8.0.1 (#14705)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 09:28:46 -10:00
dependabot[bot] 73f305ff9c Bump tornado from 6.5.4 to 6.5.5 (#14704)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 09:28:19 -10:00
J. Nick Koston 4260ca4b50 [socket] Fix use-after-free in LWIP PCB close/abort path
Clear LWIP callbacks (tcp_arg, tcp_recv, tcp_err) before calling
tcp_close() or tcp_abort() to prevent use-after-free.

After tcp_close(), the PCB remains alive during the TCP close
handshake (FIN_WAIT, TIME_WAIT states). If LWIP calls recv/err
callbacks during this period and the socket object has already
been destroyed, the callback writes to freed memory, corrupting
the heap.

This was observed as umm_malloc_core crashes on ESP8266 during
rapid API client connect/disconnect cycles — the heap free-list
got corrupted by a dangling callback writing to a freed
LWIPRawImpl object.

Extract pcb_detach_abort() and pcb_detach_close() helpers to
ensure all close/abort sites consistently clear callbacks first.
2026-03-11 09:26:51 -10:00
J. Nick Koston 395f6d7182 Merge remote-tracking branch 'upstream/dev' into integration 2026-03-11 09:14:31 -10:00
Jesse Hills b6ff7185e7 [ci] Dont run codeowners workflows on release or beta PRs (#14703) 2026-03-12 08:04:07 +13:00
J. Nick Koston 928f6f1866 [ci] Add PR title check for unescaped angle brackets (#14701) 2026-03-12 07:57:43 +13:00
J. Nick Koston 6cc1d191fd Merge remote-tracking branch 'upstream/dev' into integration 2026-03-11 08:46:55 -10:00
Jesse Hills e7c3277eeb Bump version to 2026.4.0-dev 2026-03-12 07:34:53 +13:00
Kevin Ahrendt bef5e4de9c [speaker_source] Add announcement pipeline (#14654) 2026-03-11 08:29:17 -10:00
04bcd9f56b [dashboard] Use sys.executable for dashboard subprocess commands (#14698)
Co-authored-by: Jonathan Swoboda <swoboda1337@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-03-11 14:25:36 -04:00
Jonathan SwobodaandClaude Opus 4.6 03c0ce704b Bump pyupgrade to v3.21.2 for Python 3.14 compatibility (#14699)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:22:48 -10:00
Kevin Ahrendt b27165a842 [speaker_source] Add shuffle support (#14653) 2026-03-11 08:11:00 -10:00
3d4ebe74ce [sensirion_common] Use SmallBufferWithHeapFallback helper (#14270)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-03-11 08:00:42 -10:00
Kevin Ahrendt 4e16f270a3 [speaker_source] Add playlist management (#14652) 2026-03-11 07:47:58 -10:00
J. Nick Koston 9977dd7295 Merge branch 'fast-nodelay' into integration 2026-03-10 22:40:32 -10:00
J. Nick Koston a9c2be5193 Check socket type before accessing pcb.tcp union member
Move the NETCONN_TCP type check before the pcb.tcp null check
to avoid reading the wrong union member on non-TCP sockets.
2026-03-10 22:39:36 -10:00
J. Nick Koston 17c144bed2 Merge branch 'fast-nodelay' into integration 2026-03-10 22:32:13 -10:00
J. Nick Koston ef9f34b9ab Include lwip_fast_select.h for esphome_lwip_set_nodelay declaration
The forward declaration of struct lwip_sock alone is not enough -
the fast path in setsockopt() needs the function declaration too.
2026-03-10 22:31:48 -10:00