diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc index c67677137c1c1..f5c1e74546427 100644 --- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc +++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc @@ -81,8 +81,20 @@ void WaylandBufferManagerHost::OnChannelDestroyed() { buffer_backings_.clear(); dma_buffers_.clear(); - for (auto* window : connection_->window_manager()->GetAllWindows()) - window->OnChannelDestroyed(); + // WaylandWindow::OnChannelDestroyed() may reach delegate()->OnStateUpdate() + // (via MaybeProcessPendingFrame -> OnSequencePoint), which is documented to + // be able to synchronously destroy platform windows. Snapshot weak pointers + // and re-check liveness on each iteration so a window destroyed earlier in + // the loop is skipped instead of dereferenced after free. + std::vector> windows; + for (auto* window : connection_->window_manager()->GetAllWindows()) { + windows.push_back(window->AsWeakPtr()); + } + for (auto& window : windows) { + if (window) { + window->OnChannelDestroyed(); + } + } buffer_manager_gpu_associated_.reset(); receiver_.reset();