Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlowBox#bind_model results in an invalid memory access #76

Open
BigBoyBarney opened this issue Dec 24, 2024 · 1 comment
Open

FlowBox#bind_model results in an invalid memory access #76

BigBoyBarney opened this issue Dec 24, 2024 · 1 comment

Comments

@BigBoyBarney
Copy link

Hi!
I'm sorry for opening so many issues in succession 😩

The following snippet results in an invalid memory access.

flowbox = Gtk::FlowBox.new
create_flow_box_widget = ->(item : GObject::Object) : Gtk::Widget { Gtk::Label.new(label: "hello") }
string_list = Gtk::StringList.new("")
flowbox.bind_model(model: string_list, create_widget_func: create_flow_box_widget)
I looked at the generated bindings too, which make perfect sense I think.
def bind_model(model : Gio::ListModel?, create_widget_func : Gtk::FlowBoxCreateWidgetFunc) : Nil
  # gtk_flow_box_bind_model: (Method)
  # @model: (nullable)
  # @create_widget_func:
  # @user_data: (nullable)
  # @user_data_free_func:
  # Returns: (transfer none)
 
  # Generator::NullableArrayPlan
  model = if model.nil?
            Pointer(Void).null
          else
            model.to_unsafe
          end
  # Generator::CallbackArgPlan
  if create_widget_func
    _box = ::Box.box(create_widget_func)
    create_widget_func = ->(lib_item : Pointer(Void), lib_user_data : Pointer(Void)) {
      # Generator::BuiltInTypeArgPlan
      item = GObject::Object.new(lib_item, GICrystal::Transfer::None)
      ::Box(Proc(GObject::Object, Gtk::Widget)).unbox(lib_user_data).call(item)
    }.pointer
    user_data = GICrystal::ClosureDataManager.register(_box)
    user_data_free_func = ->GICrystal::ClosureDataManager.deregister(Pointer(Void)).pointer
  else
    create_widget_func = user_data = user_data_free_func = Pointer(Void).null
  end

  # C call
  LibGtk.gtk_flow_box_bind_model(to_unsafe, model, create_widget_func, user_data, user_data_free_func)

  # Return value handling
end
Here is the error message as well.
Invalid memory access (signal 11) at address 0x0      
[0x430136] *Exception::CallStack::print_backtrace:Nil +118 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x41d736] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil) +310 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x7f9d4d8d7090] ?? +140313587708048 in /lib64/libc.so.6
[0x7f9d4de49e34] ?? +140313593421364 in /lib64/libgtk-4.so.1
[0x7f9d4de636e5] ?? +140313593525989 in /lib64/libgtk-4.so.1
[0x7f9d4de65821] ?? +140313593534497 in /lib64/libgtk-4.so.1
[0x7f9d4de65961] ?? +140313593534817 in /lib64/libgtk-4.so.1
[0x7f9d4de47937] ?? +140313593411895 in /lib64/libgtk-4.so.1
[0x7f9d4e66ef27] g_type_create_instance +599 in /lib64/libgobject-2.0.so.0
[0x7f9d4e6541c4] ?? +140313601851844 in /lib64/libgobject-2.0.so.0
[0x7f9d4e6557de] g_object_new_with_properties +574 in /lib64/libgobject-2.0.so.0
[0x7f9d4e656801] g_object_new +193 in /lib64/libgobject-2.0.so.0
[0x7f9d4dde6dee] ?? +140313593015790 in /lib64/libgtk-4.so.1
[0x7f9d4e66ef27] g_type_create_instance +599 in /lib64/libgobject-2.0.so.0
[0x7f9d4e6541c4] ?? +140313601851844 in /lib64/libgobject-2.0.so.0
[0x7f9d4e6557de] g_object_new_with_properties +574 in /lib64/libgobject-2.0.so.0
[0x7f9d4e656801] g_object_new +193 in /lib64/libgobject-2.0.so.0
[0x4e9676] *Gtk::FlowBox::new:Gtk::FlowBox +6 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x401e0f] __crystal_main +1055 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x46f2b6] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x46f22a] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +58 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x40f4f6] main +6 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x7f9d4d8c0248] ?? +140313587614280 in /lib64/libc.so.6
[0x7f9d4d8c030b] __libc_start_main +139 in /lib64/libc.so.6
[0x401925] _start +37 in /home/barney/.cache/crystal/crystal-run-window.tmp
[0x0] ???

There's a relatively high chance that this issue is self-inflicted and I'm misusing the method, in which case I would like to apologise.

@BlobCodes
Copy link
Contributor

I think the create_widget_func returns the crystal wrapper to gtk and not the widget
Also I think gtk wants a full transfer

- ::Box(Proc(GObject::Object, Gtk::Widget)).unbox(lib_user_data).call(item)
+ tmp = ::Box(Proc(GObject::Object, Gtk::Widget)).unbox(lib_user_data).call(item)
+ GICrystal.ref(tmp)
+ tmp.to_unsafe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants