Gtk::Application::get_default segfault on exit

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Gtk::Application::get_default segfault on exit

David Mugnai
According to the docs this code should be correct

    #include <gtkmm.h>

    class HelloWorld : public Gtk::Window {
      public:
    HelloWorld() : m_button("Hello World") {
    m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked));
    add(m_button);
    m_button.show();
    }

      protected:
    void on_button_clicked() {
    Gtk::Application::get_default();
    }
    Gtk::Button m_button;
    };

    int main() {
    auto app = Gtk::Application::create();
    HelloWorld helloworld;
    app->run(helloworld);
    return 0;
    }

but it segfaults when closing the window (in app->run()) if "Gtk::Application::get_default();" has been called.

gtkmm version is 3.22.0 (as shipped by Ubuntu 17.04)
    ii  libgtk-3-0:amd64             3.22.11-0ubuntu3         amd64        GTK+ graphical user interface library
    ii  libgtk-3-bin                 3.22.11-0ubuntu3         amd64        programs for the GTK+ graphical user interface library
    ii  libgtk-3-common              3.22.11-0ubuntu3         all          common files for the GTK+ graphical user interface library
    ii  libgtk-3-dev:amd64           3.22.11-0ubuntu3         amd64        development files for the GTK+ library
    ii  libgtk-3-doc                 3.22.11-0ubuntu3         all          documentation for the GTK+ graphical user interface library
    ii  libgtkmm-3.0-1v5:amd64       3.22.0-1                 amd64        C++ wrappers for GTK+ (shared libraries)
    ii  libgtkmm-3.0-dev:amd64       3.22.0-1                 amd64        C++ wrappers for GTK+ (development files)
    ii  libgtkmm-3.0-doc             3.22.0-1                 all          C++ wrappers for GTK+ (documentation)


Valgrind reports several invalid reads, this is the first one:

    ==26534== Invalid read of size 8
    ==26534==    at 0x77CD5FB: g_application_run (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5200.0)
    ==26534==    by 0x5129081: Gtk::Application::run(Gtk::Window&) (in /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1.1.0)
    ==26534==    by 0x44B032: main (main.cpp:25)
    ==26534==  Address 0x11c333c8 is 264 bytes inside a block of size 288 free'd
    ==26534==    at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==26534==    by 0x8458321: g_type_free_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x845C09F: g_value_unset (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x844F8D2: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x844FC6E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x77CD5FA: g_application_run (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5200.0)
    ==26534==    by 0x5129081: Gtk::Application::run(Gtk::Window&) (in /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1.1.0)
    ==26534==    by 0x44B032: main (main.cpp:25)
    ==26534==  Block was alloc'd at
    ==26534==    at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==26534==    by 0x86C7988: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
    ==26534==    by 0x86DFED2: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
    ==26534==    by 0x86E04FD: g_slice_alloc0 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
    ==26534==    by 0x8458058: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x8439EAA: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x843B8A7: g_object_newv (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
    ==26534==    by 0x605EB89: Glib::Object::Object(Glib::ConstructParams const&) (in /usr/lib/x86_64-linux-gnu/libglibmm-2.4.so.1.3.0)
    ==26534==    by 0x5AFA741: Gio::Application::Application(Glib::ConstructParams const&) (in /usr/lib/x86_64-linux-gnu/libgiomm-2.4.s
    o.1.3.0)
    ==26534==    by 0x51293DD: Gtk::Application::Application(Glib::ustring const&, Gio::ApplicationFlags) (in /usr/lib/x86_64-linux-gnu
    /libgtkmm-3.0.so.1.1.0)
    ==26534==    by 0x51294ED: Gtk::Application::create(Glib::ustring const&, Gio::ApplicationFlags) (in /usr/lib/x86_64-linux-gnu/libg
    tkmm-3.0.so.1.1.0)
    ==26534==    by 0x44AFF6: main (main.cpp:23)

It's a bug in gtk, gtkmm or in the Ubuntu packages?

Regards,
david
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
On 20 June 2017 at 22:22, David Mugnai <[hidden email]> wrote:
but it segfaults when closing the window (in app->run()) if "Gtk::Application::get_default();" has been called. 
[...] 
Valgrind reports several invalid reads, this is the first one:

   ==26534== Invalid read of size 8
   ==26534==    at 0x77CD5FB: g_application_run (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5200.0)
   ==26534==    by 0x5129081: Gtk::Application::run(Gtk::Window&) (in /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1.1.0)
   ==26534==    by 0x44B032: main (main.cpp:25)
   ==26534==  Address 0x11c333c8 is 264 bytes inside a block of size 288 free'd
   ==26534==    at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   ==26534==    by 0x8458321: g_type_free_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x845C09F: g_value_unset (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x844F8D2: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x844FC6E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x77CD5FA: g_application_run (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5200.0)
   ==26534==    by 0x5129081: Gtk::Application::run(Gtk::Window&) (in /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1.1.0)
   ==26534==    by 0x44B032: main (main.cpp:25)
   ==26534==  Block was alloc'd at
   ==26534==    at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   ==26534==    by 0x86C7988: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
   ==26534==    by 0x86DFED2: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
   ==26534==    by 0x86E04FD: g_slice_alloc0 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5200.0)
   ==26534==    by 0x8458058: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x8439EAA: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x843B8A7: g_object_newv (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5200.0)
   ==26534==    by 0x605EB89: Glib::Object::Object(Glib::ConstructParams const&) (in /usr/lib/x86_64-linux-gnu/libglibmm-2.4.so.1.3.0)
   ==26534==    by 0x5AFA741: Gio::Application::Application(Glib::ConstructParams const&) (in /usr/lib/x86_64-linux-gnu/libgiomm-2.4.s
   o.1.3.0)
   ==26534==    by 0x51293DD: Gtk::Application::Application(Glib::ustring const&, Gio::ApplicationFlags) (in /usr/lib/x86_64-linux-gnu
   /libgtkmm-3.0.so.1.1.0)
   ==26534==    by 0x51294ED: Gtk::Application::create(Glib::ustring const&, Gio::ApplicationFlags) (in /usr/lib/x86_64-linux-gnu/libg
   tkmm-3.0.so.1.1.0)
   ==26534==    by 0x44AFF6: main (main.cpp:23)

It's a bug in gtk, gtkmm or in the Ubuntu packages?

My guess: none of the above. Rather, due to your version of glibmm missing this patch:


meaning that the returned Application is not referenced, and can be double-freed; see the Bugzilla.
 


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
That patch was included in glibmm 2.50.1, released on 2017-04-04. So if you have an older version, it's almost certainly that. What version do you have there?

(It'll also be in glibmm 2.52, the new but API-fluid stable branch, although a stable release of that has not been made yet.)


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
In reply to this post by Daniel Boles
(sorry for the spam)

On 20 June 2017 at 22:43, Daniel Boles <[hidden email]> wrote:

meaning that the returned Application is not referenced, and can be double-freed

specifically, if I'm right, it IS double-freed, plus you try to use it after the 1st free:
  • you instantiate an unnamed RefPtr<Application> from get_default()
  • it immediately gets destroyed and decrements the reference count
  • which, because it didn't increment upon construction, causes the Application to get destroyed
  • then, on closing the window, it calls something on the Application to say 'one of your windows is gone', but there IS no Application!
  • boom.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
In reply to this post by Daniel Boles
On 20 June 2017 at 22:56, David Mugnai <[hidden email]> wrote:
Excerpts from Daniel Boles's message of June 20, 2017 11:47 pm:
That patch was included in glibmm 2.50.1, released on 2017-04-04. So if you
have an older version, it's almost certainly that. What version do you have
there?

I think you are right, the glibmm version (shipped with Ubuntu 17.04) is
2.50.0

I need to check what Debian unstable has, but I'm guessing it has .1 because I use get_default() and haven't had any crashes nor warnings from UBsan (with g++-6).

 
(It'll also be in glibmm 2.52, the new but API-fluid stable branch,
although a stable release of that has not been made yet.)

API-fluid because it is not yet released or because it will be shipped
with gtkmm 4?

Sorry, I realised after sending that I jumbled some words up there, and it wouldn't have been a good description even if I hadn't!

glibmm 2.52 is a new release in the glibmm-2.4 ABI. That is and will continue to be the major version of glibmm that underpins gtkmm-3. Unlike glibmm 2.50, version 2.52 gains a bit of leeway to add/remove API (but not break ABI) in cases where the existing API is deficient or buggy: symbols I can be removed, deprecated, or added if there's a good justification.

Fwiw, adding the refreturn to Application::get_default() just affects the generated method body, so it's not a break of either ABI or API.

In contrast, gtkmm-4 will use the next ABI of glibmm, i.e. the one that will evolve from the current master branch. I'm not sure what version number that will eventually have (maybe 2.54 or 2.6; I guess it depends how long it takes to mature).


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

aitor_czr
In reply to this post by David Mugnai

Hi,

El 21/06/17 a las 00:04, Daniel Boles [hidden email] escribió:
meaning that the returned Application is not referenced, and can be
double-freed
specifically, if I'm right, it IS double-freed, plus you try to use it
after the 1st free:

   - you instantiate an unnamed RefPtr<Application> from get_default()
   - it immediately gets destroyed and decrements the reference count
   - which, because it didn't increment upon construction, causes the
   Application to get destroyed
   - then, on closing the window, it calls something on the Application to
   say 'one of your windows is gone', but there IS no Application!
   - boom.

Instanciating a named RefPtr<Application>, i get the same segmentation fault:

Glib::RefPtr<Gio::Application> app1 =  Gtk::Application::get_default();

Running the app from the command line, the terminal holds at the third click on the button.

Something similar happens to me in simple-netaid-gtk, the terminal holds after closing the window, i don't know why. So, added exit(0) to the destructor of the mainwindow, as you can see in window_main.cpp:

https://git.devuan.org/aitor_czr/simple-netaid-gtk/blob/master/src/window_main.cpp

Cheers,

  Aitor.





 

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
Of course, you can both work around this until your distro gets the new version of glibmm, by manually adding a the_refptr->reference() before it gets destroyed. If your source might be build on arbitrary machines, then this workaround could be made conditional on the glibmm version using a macro.

(Obviously you can't use an unnamed temporary for this, but in reality that was just for a concise bug replication; there would be no reason to not assign the return value to a variable in real code.)

Be sure to prevent the extra ->reference() being compiled on systems that have the fix (whether it's your own after an upgrade, or end-users compiling your program), otherwise it will of course cause memory leaks as the refcount will be 1 too high under fixed glibmm.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Gtk::Application::get_default segfault on exit

Daniel Boles
On 21 June 2017 at 20:34, Daniel Boles <[hidden email]> wrote:

(Obviously you can't use an unnamed temporary for this...)

Well, you could, but it would still be pointless to call the function in the first place if you never do anything with it :P


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Loading...