After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 731126 - Gtk::Application destructor never called
Gtk::Application destructor never called
Status: RESOLVED FIXED
Product: gtkmm
Classification: Bindings
Component: build
3.10.x
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2014-06-02 20:27 UTC by Glenn Rice
Modified: 2014-06-09 08:23 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Glenn Rice 2014-06-02 20:27:37 UTC
The destructor of a Gtk::Application is never called.  Any of your examples demonstrate this behavior.  I realize that the Gtk::Application object (wrapped in a RefPtr) will exist for the lifetime of the application, and you are probably assuming that the garbage collector will take care of cleaning it up.  However, that is a flaw.  The destructor should be able to take care of things that need to be done when the app is closed.  For example releasing hardware that has opened by the app.  In general it is bad practice to rely on a garbage collector to clean things up in any case.
Comment 1 Kjell Ahlstedt 2014-06-04 09:49:48 UTC
I made some tests with the gdb debugger, and set breakpoints at
Gtk::Application::~Application() and gtk_application_finalize().

I tested some of the example programs in the Gtkmm tutorial,
https://git.gnome.org/browse/gtkmm-documentation/tree/examples

book/application/app_and_win_menus
   Neither the destructor nor the finalize function is called.

book/application/command_line_handling
book/application/simple
   Only the finalize function is called.

book/box
book/progressbar
   Both the destructor and the finalize function are called.

I'll try to find out what's wrong with the book/application examples.
Do you know other example programs where the Gtk::Application destructor is
not called?
Comment 2 Glenn Rice 2014-06-04 11:35:20 UTC
Those are the examples that I observed the problem on, and I haven't tested any others.  However, I originally observed it in an application that I develop.  It seems to at least occur anytime you derive from the Gtk::Application class.
Comment 3 Kjell Ahlstedt 2014-06-06 16:39:55 UTC
I want to modify my statements in comment 1.
When I tested more carefully I noticed:

book/application/app_and_win_menus
   Neither the destructor nor the finalize function is called, if the
   program is stopped with the menu item Gtk::Application->Quit.
   Both the destructor and the finalize function are called, if the
   program is stopped with the close button in the title bar.

book/application/command_line_handling
book/application/simple
book/box
book/progressbar
   Both the destructor and the finalize function are called.

It looks like gdb sometimes misses a breakpoint in the empty
Gtk::Application::~Application(). I got more reliable results when I set the
breakpoint in Gio::Application::~Application().

The problem with the book/application/app_and_win_menus example is that it
uses Gio::Application::quit(). I've pushed commit
https://git.gnome.org/browse/gtkmm-documentation/commit/?id=ada1f833c11d89200fe75cea4217f5150b4098c8
which adds the following explanation:

  // Gio::Application::quit() will make Gio::Application::run() return,
  // but it's a crude way of ending the program. The window is not removed
  // from the application. Neither the window's nor the application's
  // destructors will be called, because there will be remaining reference
  // counts in both of them. If we want the destructors to be called, we
  // must remove the window from the application. One way of doing this
  // is to hide the window.

Is this enough of a fix for this bug?

The implications of using Gio::Application::quit() are not well documented.
A better documentation should start in glib or gtk+. Most of the documentation
in glibmm and gtkmm is copied from there. It's not obvious where to add such
clarifying documentation. It does not fit in the documentation of
g_application_quit(). Glib is not supposed to know anything about windows.
Windows belong to gtk+.
Comment 4 Glenn Rice 2014-06-06 19:38:54 UTC
I suppose.  It seems like a bit of workaround, and not much of a fix, but I guess it will do.
Comment 5 Kjell Ahlstedt 2014-06-08 09:25:47 UTC
I agree that it's more like a workaround than a real fix.

I have updated the documentation of Gtk::Application::add_window() and the
run() methods that take a Window& argument.
https://git.gnome.org/browse/gtkmm/commit/?id=feedeed8c45cca9c19f18300c84328579aa69c4c

I think this is all we can reasonably do.
It's not reasonable to add anything concerning windows to Gio::Application::
quit().
How about letting Gtk::Application::run() add a 'shutdown' signal handler?
And letting that handler remove all windows that are still connected to the
application? There are two problems with such a solution:
1. I think it would count as an API break.
2. The shutdown signal is emitted only in the primary application instance.

I close this bug with these documentation fixes.
Feel free to reopen it, if you think more can and should be done.
Comment 6 Kjell Ahlstedt 2014-06-09 08:23:47 UTC
I jumped to conclusions when I tested book/application/app_and_win_menus.
Only the application's destructor is affected by remove_window(). To have a
dynamically allocated window's destructor called, the window must be
explicitly deleted.

I've pushed a patch with corrected Gtk::Application documentation.
The updated documentation only tells what happens to the application's dtor.
https://git.gnome.org/browse/gtkmm/commit/?id=c5a9f7883580af9314a6f450c0ed7e80f788b912