From 9e4757ac811ffe829f3e15eddb903f403dd3232c Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Tue, 22 Sep 2026 03:13:10 -0700 Subject: [PATCH 1/3] inspector: fix null request_queue dereference in InspectorIo request_queue_ is only assigned on the IO thread and may still be null when Start() checks Expired(). Return nullptr there and guard the destructor, which runs on that failure path. Signed-off-by: Aaron Lichtman --- src/inspector_io.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/inspector_io.cc b/src/inspector_io.cc index e0b4b6c37461..c9624ab63a1d 100644 --- a/src/inspector_io.cc +++ b/src/inspector_io.cc @@ -250,7 +250,8 @@ std::unique_ptr InspectorIo::Start( path, host_port, inspect_publish_uid)); - if (io->request_queue_->Expired()) { // Thread is not running + if (io->request_queue_ == nullptr || + io->request_queue_->Expired()) { // Thread is not running return nullptr; } return io; @@ -272,7 +273,8 @@ InspectorIo::InspectorIo(std::shared_ptr main_thread, } InspectorIo::~InspectorIo() { - request_queue_->Post(0, TransportAction::kKill, nullptr); + if (request_queue_ != nullptr) + request_queue_->Post(0, TransportAction::kKill, nullptr); int err = uv_thread_join(&thread_); CHECK_EQ(err, 0); } From 76800758700bf5cea87fee4ecb237d63d53b3ae2 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 23 Sep 2026 09:37:03 -0700 Subject: [PATCH 2/3] Revert "inspector: fix null request_queue dereference in InspectorIo" This reverts commit 9e4757ac811ffe829f3e15eddb903f403dd3232c. Signed-off-by: Aaron Lichtman --- src/inspector_io.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/inspector_io.cc b/src/inspector_io.cc index c9624ab63a1d..e0b4b6c37461 100644 --- a/src/inspector_io.cc +++ b/src/inspector_io.cc @@ -250,8 +250,7 @@ std::unique_ptr InspectorIo::Start( path, host_port, inspect_publish_uid)); - if (io->request_queue_ == nullptr || - io->request_queue_->Expired()) { // Thread is not running + if (io->request_queue_->Expired()) { // Thread is not running return nullptr; } return io; @@ -273,8 +272,7 @@ InspectorIo::InspectorIo(std::shared_ptr main_thread, } InspectorIo::~InspectorIo() { - if (request_queue_ != nullptr) - request_queue_->Post(0, TransportAction::kKill, nullptr); + request_queue_->Post(0, TransportAction::kKill, nullptr); int err = uv_thread_join(&thread_); CHECK_EQ(err, 0); } From 05eeb2ef7c2431c9006d7082ec0a8faba869c368 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 23 Sep 2026 09:37:31 -0700 Subject: [PATCH 3/3] inspector: handle spurious wakeups in InspectorIo startup The constructor waited on thread_start_condition_ without a predicate, so a spurious wakeup could let it return before the IO thread assigned request_queue_, leading to a null dereference in Start(). Loop until request_queue_ is set. Signed-off-by: Aaron Lichtman Assisted-by: Codex --- src/inspector_io.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inspector_io.cc b/src/inspector_io.cc index e0b4b6c37461..9065aabfc692 100644 --- a/src/inspector_io.cc +++ b/src/inspector_io.cc @@ -268,7 +268,7 @@ InspectorIo::InspectorIo(std::shared_ptr main_thread, id_(GenerateID()) { Mutex::ScopedLock scoped_lock(thread_start_lock_); CHECK_EQ(uv_thread_create(&thread_, InspectorIo::ThreadMain, this), 0); - thread_start_condition_.Wait(scoped_lock); + while (request_queue_ == nullptr) thread_start_condition_.Wait(scoped_lock); } InspectorIo::~InspectorIo() {