Repository navigation
output: skip lock surface creation when the session lock is gone - #1080
Open
Karen-Abgaryan wants to merge 1 commit into
Open
Karen-Abgaryan wants to merge 1 commit into
Karen-Abgaryan wants to merge 1 commit into
Conversation
Lock surface creation was skipped once the session lock object was released, preventing a null dereference when wl_output.done arrived during unlock.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
hyprlock segfaults if a new output's
wl_output.doneis dispatched after the session lock object has been released. Hyprland then shows the "lockscreen app died" screen and the session stays locked.I hit this after resuming a laptop with an external monitor. Right after wake the monitor disconnected and reconnected several times while hyprlock was unlocking.
releaseSessionLock()andonLockFinished()setm_sLockState.lockto null but never resetm_lockAquired, soisLockAquired()keeps returning true. If adoneevent for a newly bound output arrives after that, thesetDonehandler callscreateSessionLockSurface(), and theCSessionLockSurfaceconstructor callsg_pHyprlock->getSessionLock()->sendGetLockSurface(...)on the null lock. In my case the event was dispatched by thewl_display_roundtrip()at the end ofreleaseSessionLock().Trace from the core dump:
Fix
createSessionLockSurface()returns early whengetSessionLock()is null. The check sits next to the existing guards, at the point that dereferences the lock. So it covers every caller (thedonehandler andacquireSessionLock()) and both paths that drop the lock object.An alternative would be resetting
m_lockAquiredinreleaseSessionLock()/onLockFinished(). I went with the guard at where the null dereference happens, so it protects any caller, including future ones. Happy to switch if you prefer that.Related: #1025 touched the same function for outputs appearing during resume.
Testing
I ran everything in a nested Hyprland. Real hotplug rarely hits the window after
releaseSessionLock()drops the lock, so forced it with gdb.mainand of this branch. With-O3the breakpoint line gets inlined away.Output.cpp:40(thesetGeometryregistration inCOutput::create) that callsreleaseSessionLock()and then continues.hyprctl output create headless FORCED.main: SIGSEGV afteroutput N creating a new lock surface.output N has no session lock to create a lock surface forand exits normally.AI usage disclosure
I used Claude throughout. It symbolized the core dump with gdb/debuginfod, traced the crash path and found the stale
m_lockAquiredflag. It proposed and wrote the 7-line fix and the commit message. It also built and ran every test listed above, in the nested Hyprland.