Skip to content

Bugfix segfaults when changing font/window size#1922

Open
jquast wants to merge 1 commit intocontour-terminal:masterfrom
jquast:jq/bugfix-crashes-on-resizes
Open

Bugfix segfaults when changing font/window size#1922
jquast wants to merge 1 commit intocontour-terminal:masterfrom
jquast:jq/bugfix-crashes-on-resizes

Conversation

@jquast
Copy link
Copy Markdown
Contributor

@jquast jquast commented Mar 28, 2026

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 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.

(Probably) closes #1712 and #408

Checklist

  • I have read the CONTRIBUTING guide
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • Breaking changes (if any) are documented

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.

@github-actions github-actions bot added VT: Backend Virtual Terminal Backend (libterminal API) frontend Contour Terminal Emulator (GUI frontend) VT: rasterizer Rendering of the terminal into a pixmap using `terminal_renderer` library labels Mar 28, 2026
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend Contour Terminal Emulator (GUI frontend) VT: Backend Virtual Terminal Backend (libterminal API) VT: rasterizer Rendering of the terminal into a pixmap using `terminal_renderer` library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash on Windows when agressively resizing.

1 participant