[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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user