[Memory] Fix watch race condition causing crashes on Linux

When two threads fault on the same watched page, the second thread may
find the watch already cleared by the first. TriggerCallbacks returned
false in this case, leaving the SIGSEGV unhandled. Return true instead
so the instruction retries — the page is already unprotected.

This is the signal-safe equivalent of the QueryProtect check that
handles the same race on Windows. Fixes a regression from dbd58b.
This commit is contained in:
Herman S.
2026-03-12 14:09:19 +09:00
parent 5f62db9289
commit 3b8debcf5b

View File

@@ -1932,7 +1932,13 @@ bool PhysicalHeap::TriggerCallbacks(
}
}
if (!any_watched) {
return false;
// No watches on this page — another thread already cleared them (race
// condition between the fault firing and acquiring the lock). Return true
// so the faulting instruction retries; the page is now unprotected and the
// access will succeed. This is the signal-safe equivalent of the
// QueryProtect check in the non-Linux path of
// MMIOHandler::ExceptionCallback.
return true;
}
// Trigger callbacks.