garrigue / lablgtk

LablGTK 2 and 3: an interface to the GIMP Tool Kit
https://garrigue.github.io/lablgtk
Other
89 stars 40 forks source link

Segfault when initializing class using window #113

Open vrotaru opened 4 years ago

vrotaru commented 4 years ago

I have a simple program which works with lablgtk2 but segfaults with lablgtk3. The program

class wrapper =
  let window = GWindow.window ~title: "demo" ~show: false ()
  in
  object (_self)
    inherit GObj.widget window#as_widget

    method window  = window 
  end

let _ =
  let _locale = GMain.init () in
  let wrapper =  new wrapper in
  ignore@@ wrapper#window#connect#destroy ~callback: GMain.quit;

  wrapper#window#present ();
  GMain.main ()

And I compile it using

ocamlfind ocamlc -package lablgtk3 -linkpkg -thread -g -o demo demo.ml

And when I run it segfaults wtih the following stack trace

systemd-coredump[60499]: Process 60497 (demo) of user 1000 dumped core.

Stack trace of thread 60497:
#0  0x00007f56c2ae4acc n/a (libgtk-3.so.0 + 0x112acc)
#1  0x00007f56c2b04b3c n/a (libgtk-3.so.0 + 0x132b3c)
#2  0x00007f56c2aef175 n/a (libgtk-3.so.0 + 0x11d175)
#3  0x00007f56c263c687 g_type_create_instance (libgobject-2.0.so.0 + 0x30687)
#4  0x00007f56c262ce9e n/a (libgobject-2.0.so.0 + 0x20e9e)
#5  0x00007f56c262dfdd g_object_new_with_properties (libgobject-2.0.so.0 + 0x21fdd)
#6  0x00007f56c262eae2 g_object_new (libgobject-2.0.so.0 + 0x22ae2)
#7  0x00007f56c2d088e3 n/a (libgtk-3.so.0 + 0x3368e3)
#8  0x00007f56c263c687 g_type_create_instance (libgobject-2.0.so.0 + 0x30687)
#9  0x00007f56c262ce9e n/a (libgobject-2.0.so.0 + 0x20e9e)
#10 0x00007f56c262e251 g_object_newv (libgobject-2.0.so.0 + 0x22251)
#11 0x00007f56c31ad8c0 ml_g_object_new (dlllablgtk3_stubs.so + 0x378c0)
#12 0x0000558742baba9d caml_interprete (ocamlrun + 0x32a9d)
#13 0x0000558742bae897 caml_main (ocamlrun + 0x35897)
#14 0x0000558742b8d70c main (ocamlrun + 0x1470c)
#15 0x00007f56c3d91002 __libc_start_main (libc.so.6 + 0x27002)
#16 0x0000558742b8d74e _start (ocamlrun + 0x1474e)
vrotaru commented 4 years ago

Now if I compile the same program with lablgtk2 everything works.

It also works if I move the line

let _locale = GMain.init ()

to the start of the program. Hope this helps.

vrotaru commented 4 years ago

I guess I've seen the wrongness of my ways. The window is created at class definition time, not at object instantiation time. This changes are enough to fix the problem

- class wrapper =
+ class wrapper () =
-   let wrapper = new wrapper
+   let wrapper = new wrapper ()

to fix the problem. Still it will be nice to have a check is_gtk_main_initialized before the ml_g_object_new is called. Not sure how hard is this to add.

garrigue commented 4 years ago

The semantics of let in parameterless classes is very confusing. Basically the let is executed at class initialization time, but a new object will be created each time you call new.

I was not aware of the change of behavior between Gtk2 and Gtk3, since the change is not on the lablgtk side. Of course, the code is incorrect under Gtk2 too, as the critical warning shows.

As for checking for initialization, we could do it before creating widgets. It is very simple to add for wrappers generated by propcc, but there may be a few raw *_new functions around, which would require adding the check by hand.