Bugfix segfaults when changing font/window size#1922
Open
jquast wants to merge 1 commit intocontour-terminal:masterfrom
Open
Bugfix segfaults when changing font/window size#1922jquast wants to merge 1 commit intocontour-terminal:masterfrom
jquast wants to merge 1 commit intocontour-terminal:masterfrom
Conversation
Problem ------- This problem is reproduced by using ctrl+mouse wheel, it crashes most easily when "very busy", like a running "find /" command and oscillate changing the font size from very large to small and back again. It is a race condition, so being "busy" contributes to the likelyness of crashing, I had it crash with very casual use by adjusting the font size a few notches while using gambaterm, which redraws the screen at up to 60Hz, but it can be reproduced less frequently by resizing font while running ``find /`` command as captured in this recording. Analysis -------- A font change triggers updateFontMetrics() (UI thread), which rebuilds grid metrics and replaces the texture atlas while the QSG render thread is actively using them in renderImpl() (render thread). The resulting window resize has the same problem, with applyResize() updating page size and margins without mutex. About four different segfaults were possible due to a race condition that can get null atlas dereferences, corrupted line buffers, or assertion failures on atlas dimensions. Additionally, another race in setGuiTabInfoForStatusLine() does an unprotected std::move of a TabsInfo struct (from UI thread) while the terminal thread copies it under _stateMutex, causing heap corruption. Solution -------- Added _renderMutex to Renderer, held by all geometry/atlas writers and renderImpl(). The TabsInfo fix just acquires _stateMutex on the writer side to match the reader.
4cf953e to
861190f
Compare
This was referenced Mar 28, 2026
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
This problem is reproduced by using ctrl+mouse wheel, and crashes more frequently when "very busy" with the render thread, it is a race condition. I had it crash with very casual use by adjusting the font size a few notches while using gambaterm, which has 60Hz full screen redraws with the DEC synchronized output sequence, but it can be reproduced with a little more effort (resizing with very large point sizes) by running
find /command, as captured in this recording:contour-crash-resize-.2.mp4
I would say this crash is a little rare, that a majority of users should not experience it.
Analysis
A font change triggers
updateFontMetrics()(UI thread), which rebuilds grid metrics and replaces the texture atlas while the QSG render thread is actively using them inrenderImpl()(render thread).The resulting window resize has the same problem, with
applyResize()updating page size and margins without mutex. About four different segfaults were possible due to a race condition that can get null atlas dereferences, corrupted line buffers, or assertion failures on atlas dimensions.Additionally, another race in
setGuiTabInfoForStatusLine()does an unprotectedstd::moveof aTabsInfostruct (from UI thread) while the terminal thread copies it under_stateMutex, causing heap corruption.Solution
Added
_renderMutexto Renderer, held by all geometry/atlas writers andrenderImpl(). TheTabsInfofix just acquires_stateMutexon the writer side to match the reader.(Probably) closes #1712 and #408
Checklist
no documentation or tests were added or changed, this would be very difficult to create a test for, it would require preparing and running all of these threads with real Qt / OpenGL contexts, I'm afraid I can't do that.