Prevent UI freeze when opening binary files#732
Open
oxidworks wants to merge 1 commit intolinuxmint:masterfrom
Open
Prevent UI freeze when opening binary files#732oxidworks wants to merge 1 commit intolinuxmint:masterfrom
oxidworks wants to merge 1 commit intolinuxmint:masterfrom
Conversation
Binary files typically contain no newline characters, causing the entire file content to be placed in a single GtkTextBuffer line. This triggers extremely slow Pango/HarfBuzz text shaping (O(n²) for varied content) that blocks the GTK main thread indefinitely at 100% CPU. The problem is compounded by the encoding fallback mechanism which converts each byte to a 3-character hex escape (\XX), tripling the line length. This commit adds three mitigations: 1. Pre-load binary detection in _xed_tab_load(): Before starting the file loader, check the content type via GIO and scan the first 8KB for NUL bytes. If the file appears binary, show a warning info bar with "Open Anyway" / "Don't Open" buttons instead of loading immediately. Text-like types (text/*, XML, JSON, JS, SVG) are always allowed through. 2. New xed_binary_file_warning_info_bar_new(): Creates a warning info bar showing the detected file type description and explaining that opening binary files can cause unresponsiveness. 3. Cursor position optimization in update_cursor_position_statusbar(): For lines longer than 10,000 characters, use gtk_text_iter_get_line_offset() directly instead of the O(n) character-by-character tab-width calculation loop. This prevents a secondary freeze vector when the cursor moves on very long lines. Fixes: linuxmint#491 Fixes: linuxmint#591 Related: linuxmint#624
a937d79 to
c8b1ec4
Compare
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.
Summary
Opening a binary file (e.g. an ELF executable, a
.oobject, an image) in xed causes 100% CPU usage and a complete UI freeze that can last indefinitely. The only way to recover is tokillthe process.This has been reported multiple times over the past 7+ years (#174, #491, #591, #624) and affects all xed versions using GtkSourceView.
Root cause
Binary files typically contain no newline characters, so the entire file content ends up as a single
GtkTextBufferline. The encoding fallback mechanism (insert_fallback()in GtkSourceView) converts each byte to a 3-character hex escape (\XX), tripling the length. Pango/HarfBuzz text shaping on a line with millions of characters blocks the GTK main thread indefinitely.A secondary freeze vector exists in
update_cursor_position_statusbar()which iterates character-by-character (O(n)) from the start of the line to calculate the column position.Changes
1. Pre-load binary detection (
xed-tab.c)GtkSourceFileLoader, checks the content type viag_file_query_info()text/*, XML, JSON, JavaScript, SVG) are always allowed through2. Binary file warning info bar (
xed-io-error-info-bar.c/.h)xed_binary_file_warning_info_bar_new()function3. Cursor position optimization (
xed-window.c)gtk_text_iter_get_line_offset()directly instead of the O(n) character-by-character loopTesting
/usr/bin/xed(binary): warning info bar appears, no freezeFixes #491
Fixes #591
Related: #624, #174