mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
[core] Fix null deref in WarnIfComponentBlockingGuard for self-keyed timers
Self-keyed scheduler items (Scheduler::set_timeout(self, ...) and set_interval(self, ...)) intentionally store component == nullptr. When USE_RUNTIME_STATS is enabled, WarnIfComponentBlockingGuard::finish() dereferenced component_ to call runtime_stats_.record_time(), causing a load access fault on RISC-V (e.g. ESP32-C3) when these timers fire. Skip the per-component bookkeeping when component_ is null, but still accumulate into ComponentRuntimeStats::global_recorded_us so Application::loop() overhead accounting (which subtracts scheduled callback time from before_loop_tasks_) stays accurate.
This commit is contained in:
@@ -655,7 +655,15 @@ class WarnIfComponentBlockingGuard {
|
||||
// Inlined: the fast path is just millis() + subtract + compare
|
||||
inline uint32_t HOT finish() {
|
||||
#ifdef USE_RUNTIME_STATS
|
||||
this->component_->runtime_stats_.record_time(micros() - this->started_us_);
|
||||
uint32_t elapsed_us = micros() - this->started_us_;
|
||||
// component_ is nullptr for self-keyed scheduler items (set_timeout/set_interval(self, ...))
|
||||
if (this->component_ != nullptr) {
|
||||
this->component_->runtime_stats_.record_time(elapsed_us);
|
||||
} else {
|
||||
// Still accumulate into the global counter so Application::loop() can subtract
|
||||
// this time from before_loop_tasks_ wall time.
|
||||
ComponentRuntimeStats::global_recorded_us += elapsed_us;
|
||||
}
|
||||
#endif
|
||||
uint32_t curr_time = MillisInternal::get();
|
||||
#ifndef USE_BENCHMARK
|
||||
|
||||
Reference in New Issue
Block a user