From d4d8e92243e3b213d2eefa96db815a461a2dfed1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 19 Mar 2026 00:22:31 -1000 Subject: [PATCH 1/2] [bme68x_bsec2] Store trigger time as member to avoid SBO overflow The set_timeout lambda captured [this, curr_time_ns] (4 + 8 = 12 bytes), exceeding the std::function small buffer optimization threshold (8 bytes on 32-bit) and forcing a heap allocation every measurement cycle (every 3s in LP mode). Store curr_time_ns as a class member and capture only [this] (4 bytes), which fits inline in the SBO. Trades 8 bytes of permanent member storage to eliminate a heap alloc+free cycle per measurement. --- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp | 3 ++- esphome/components/bme68x_bsec2/bme68x_bsec2.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/bme68x_bsec2/bme68x_bsec2.cpp b/esphome/components/bme68x_bsec2/bme68x_bsec2.cpp index 0210d1e67d7..ed2ec808962 100644 --- a/esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +++ b/esphome/components/bme68x_bsec2/bme68x_bsec2.cpp @@ -279,7 +279,8 @@ void BME68xBSEC2Component::run_() { uint32_t meas_dur = 0; meas_dur = bme68x_get_meas_dur(this->op_mode_, &bme68x_conf, &this->bme68x_); ESP_LOGV(TAG, "Queueing read in %uus", meas_dur); - this->set_timeout("read", meas_dur / 1000, [this, curr_time_ns]() { this->read_(curr_time_ns); }); + this->trigger_time_ns_ = curr_time_ns; + this->set_timeout("read", meas_dur / 1000, [this]() { this->read_(this->trigger_time_ns_); }); } else { ESP_LOGV(TAG, "Measurement not required"); this->read_(curr_time_ns); diff --git a/esphome/components/bme68x_bsec2/bme68x_bsec2.h b/esphome/components/bme68x_bsec2/bme68x_bsec2.h index 8f4d8f61c25..2dc1f63617c 100644 --- a/esphome/components/bme68x_bsec2/bme68x_bsec2.h +++ b/esphome/components/bme68x_bsec2/bme68x_bsec2.h @@ -116,6 +116,7 @@ class BME68xBSEC2Component : public Component { int8_t bme68x_status_{BME68X_OK}; int64_t last_time_ms_{0}; + int64_t trigger_time_ns_{0}; // Stored for set_timeout lambda to avoid exceeding std::function SBO uint32_t millis_overflow_counter_{0}; std::queue> queue_; From 6486937aa10242c3bf1a8e4dad95f433b6d9ff68 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 19 Mar 2026 00:39:05 -1000 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- esphome/components/bme68x_bsec2/bme68x_bsec2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/bme68x_bsec2/bme68x_bsec2.h b/esphome/components/bme68x_bsec2/bme68x_bsec2.h index 2dc1f63617c..240654c52b3 100644 --- a/esphome/components/bme68x_bsec2/bme68x_bsec2.h +++ b/esphome/components/bme68x_bsec2/bme68x_bsec2.h @@ -116,7 +116,7 @@ class BME68xBSEC2Component : public Component { int8_t bme68x_status_{BME68X_OK}; int64_t last_time_ms_{0}; - int64_t trigger_time_ns_{0}; // Stored for set_timeout lambda to avoid exceeding std::function SBO + int64_t trigger_time_ns_{0}; // Stored for set_timeout lambda to help avoid heap allocation on supported 32-bit toolchains with small std::function SBO uint32_t millis_overflow_counter_{0}; std::queue> queue_;