[virt-tools-list] [virt-viewer] VirtViewerApp: Never remove main window

Christophe Fergeau cfergeau at redhat.com
Mon Nov 17 17:24:35 UTC 2014

It's currently possible to destroy any virt-viewer window, including the
main window. However, some part of the code expects that the main window
is always present, for example to present status messages.

In particular, stopping the guest (or running virsh destroy) will close
all windows: virt_viewer_session_clear_displays will get called, which
will call into virt_viewer_app_remove_display_removed, and finally into
virt_viewer_app_remove_nth_window, which will destroy the window being
removed if it holds the last reference to it.

So going through virt_viewer_session_clear_displays, all
VirtViewerWindow instances and their corresponding GtkWindow have been
destroyed. This is already an issue as VirtViewerApp::main_window will
be pointing to freed memory.

When using virt-viewer --reconnect, this will cause a crash when
restarting the guest in virt_viewer_app_create_session as it tries to
get a valid GtkWindow through:
GtkWindow *window = virt_viewer_window_get_window(priv->main_window);

This commit avoids this issue by special casing the main window in
virt_viewer_app_remove_nth_window to ensure it never gets removed.
This is similar to what is done in virt_viewer_app_hide_all_windows.
 src/virt-viewer-app.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index 88db463..1d0c601 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -977,8 +977,11 @@ static void virt_viewer_app_remove_nth_window(VirtViewerApp *self,
     VirtViewerWindow *win = virt_viewer_app_get_nth_window(self, nth);
     if (!win)
     virt_viewer_window_set_display(win, NULL);
+    if (win == self->priv->main_window) {
+        g_debug("Not removing main window %d %p", nth, win);
+        return;
+    }
     g_debug("Remove window %d %p", nth, win);

More information about the virt-tools-list mailing list