fix(v3/linux): fix OpenFileDialog crash from GTK thread violation#4926
Conversation
The runChooserDialog function had a race condition that caused GTK assertion failures and crashes on Linux: 1. InvokeAsync scheduled gtk_dialog_run on the GTK thread 2. After dialog closed, a goroutine was spawned OFF the GTK thread 3. gtk_widget_destroy was called immediately (before goroutine ran) 4. Goroutine tried to call gtk_file_chooser_get_filenames on destroyed widget Fix: - Extract filenames on GTK thread BEFORE destroying widget - Call gtk_widget_destroy on GTK thread AFTER extraction - Goroutine only handles sending Go strings (no GTK calls) Fixes wailsapp#3683 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughCollect GTK file-chooser results on the GTK thread: retrieve filenames via Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@v3/pkg/application/linux_cgo.go`:
- Around line 2109-2129: The loop over filenames from
gtk_file_chooser_get_filenames stops at 1024 and only calls buildStringAndFree
for those items, causing any remaining filename strings to leak because
g_slist_free only frees nodes; modify the extraction logic in the block that
uses filenames, iter and count so you iterate the entire list: for the first up
to 1024 entries call buildStringAndFree and append into results, and for any
remaining entries call C.g_free on the gpointer(iter.data) to free the string;
after finishing the full traversal still call C.g_slist_free(filenames), then
destroy the widget and send results to selections as before (referencing
gtk_file_chooser_get_filenames, buildStringAndFree, C.g_free, C.g_slist_free,
filenames, iter, results, selections).
leaanthony
left a comment
There was a problem hiding this comment.
LGTM! This correctly fixes the GTK thread safety violation. All GTK operations now happen on the GTK thread inside InvokeAsync, and the widget is properly destroyed after extracting results.
The coderabbit comment about the 1024 limit leaking memory is technically valid but a pre-existing edge case (the limit was already there). The main crash fix is correct.
Please add an UNRELEASED_CHANGELOG.md entry for this bug fix.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When more than 1024 files are selected, the previous code leaked memory because g_slist_free() only frees list nodes, not the data pointers. Now we iterate through ALL entries, freeing each filename string. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GTK's gtk_file_chooser_get_filenames() has no documented maximum. The limit was arbitrary and unnecessary. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consistent with Windows/macOS behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
…ilsapp#4926) * fix(v3/linux): fix OpenFileDialog crash from GTK thread violation The runChooserDialog function had a race condition that caused GTK assertion failures and crashes on Linux: 1. InvokeAsync scheduled gtk_dialog_run on the GTK thread 2. After dialog closed, a goroutine was spawned OFF the GTK thread 3. gtk_widget_destroy was called immediately (before goroutine ran) 4. Goroutine tried to call gtk_file_chooser_get_filenames on destroyed widget Fix: - Extract filenames on GTK thread BEFORE destroying widget - Call gtk_widget_destroy on GTK thread AFTER extraction - Goroutine only handles sending Go strings (no GTK calls) Fixes wailsapp#3683 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: add changelog entry for OpenFileDialog crash fix Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: properly free all filenames to prevent memory leak When more than 1024 files are selected, the previous code leaked memory because g_slist_free() only frees list nodes, not the data pointers. Now we iterate through ALL entries, freeing each filename string. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: remove arbitrary 1024 file selection limit GTK's gtk_file_chooser_get_filenames() has no documented maximum. The limit was arbitrary and unnecessary. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: add comment about no file selection limit Consistent with Windows/macOS behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: ddmoney420 <ddmoney420@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Lea Anthony <lea.anthony@gmail.com>



Summary
Fixes GTK assertion failure and crash when using
OpenFileDialog()on Linux.Problem
When calling
OpenFileDialog()on Linux and selecting a file, the application crashed with:Root Cause
The
runChooserDialogfunction had a race condition and thread safety violation:InvokeAsyncscheduledgtk_dialog_runon the GTK threadgtk_widget_destroywas called immediately (outsideInvokeAsync)gtk_file_chooser_get_filenameson the destroyed widgetGTK is NOT thread-safe - all GTK operations must occur on the GTK main thread.
Solution
gtk_widget_destroyon GTK thread AFTER extractionTest plan
OpenFileDialog()from a service bindingFixes #3683
🤖 Generated with Claude Code
Summary by CodeRabbit