gircore / gir.core

A C# binding generator for GObject based libraries providing a C# friendly API surface
https://gircore.github.io/
MIT License
314 stars 29 forks source link

Strange drag and drop crash bug #1125

Closed ravener closed 1 month ago

ravener commented 1 month ago

I'm dealing with a weird crash happening with the use of Gtk.DropTarget

Strangely enough this only seems to happen inside Flatpak runtime. On both GNOME SDK 46 and 47. But I cannot reproduce it on my own machine locally (Debian 12, GNOME 43).

The problem seems related to garbage collection.

I've narrowed it down to a simple reproducible window that shows this:


namespace MyApp
{
    public class BugWindow : Adw.ApplicationWindow
    {
        private readonly Gtk.Button _button;
        private readonly Gtk.Button _button2;
        private readonly Gtk.DropTarget _drop;
        private readonly Gtk.DropTarget _drop2;
        public BugWindow(Gtk.Application app)
        {
            Application = app;

            var box = Gtk.Box.New(Gtk.Orientation.Vertical, 6);
            box.Append(Adw.HeaderBar.New());
            _button = Gtk.Button.NewWithLabel("File 1");
            _button2 = Gtk.Button.NewWithLabel("File 2");
            _button.OnClicked += OnFileSelect;
            _button2.OnClicked += OnFileSelect;
            box.Append(_button);
            box.Append(_button2);

            SetContent(box);

            _drop = Gtk.DropTarget.New(Gio.FileHelper.GetGType(), Gdk.DragAction.Copy);
            _drop.OnDrop += OnDrop;
            _button.AddController(_drop);

            _drop2 = Gtk.DropTarget.New(Gio.FileHelper.GetGType(), Gdk.DragAction.Copy);
            _drop2.OnDrop += OnDrop;
            _button2.AddController(_drop2);
        }

        private bool OnDrop(Gtk.DropTarget drop, Gtk.DropTarget.DropSignalArgs e)
        {
            System.GC.Collect(); // Force gc for stress testing.
            Console.WriteLine("dropped!");
            var file = new Gio.FileHelper(e.Value.GetObject()!.Handle, false);
            var path = file.GetPath();
            Console.WriteLine(path);

            if (File.Exists(path))
            {
                Console.WriteLine("File exists.");
                if (drop == _drop)
                {
                    _button.SetLabel(file.GetBasename()!);
                    Console.WriteLine("Set label");
                }
                else if (drop == _drop2)
                {
                    _button2.SetLabel(file.GetBasename()!);
                    Console.WriteLine("Set label 2");
                }

                return true;
            }

            return false;
        }

        private void OnFileSelect(Gtk.Button sender, EventArgs args)
        {
            Console.WriteLine("here we are.");
            var chooser = Gtk.FileChooserNative.New("Open stuff", this, Gtk.FileChooserAction.Open, null, null);
            chooser.Show();
        }
    }
}

This is the error logs

Process terminated. A callback was made on a garbage collected delegate of type 'GObject-2.0!GObject.Internal.ToggleNotify::Invoke'.
Repeat 2 times:
--------------------------------
   at GObject.Internal.Object.RemoveToggleRef(IntPtr, GObject.Internal.ToggleNotify, IntPtr)
--------------------------------
   at GObject.Internal.ObjectMapper+ToggleRef.<Dispose>b__9_0()
   at GLib.Internal.SourceFuncAsyncHandler.<.ctor>b__3_0(IntPtr)
   at Gio.Internal.Application.Run(IntPtr, Int32, System.String[])
   at Gio.Internal.Application.Run(IntPtr, Int32, System.String[])
   at Gio.Application.Run(Int32, System.String[])
   at Gio.Application.RunWithSynchronizationContext(System.String[])
   at Oto.Program.Run(System.String[])
   at Oto.Program.Main(System.String[])
>>> Error: Child process exited with code 134

Again emphasizing this happens in Flatpak runtime and only when drag and drop was used.

Here's a video demonstration:

Screencast from 2024-09-24 03-32-04.webm

badcel commented 1 month ago

This sounds a bit like while disposing the ToggleRef there is some invocation of the notify callback.

This needs to be investigated.

badcel commented 1 month ago

Good news, I can reproduce the bug on my system. I will work on the fix here: #1128