diff --git a/src/vte.c b/src/vte.c
index 01602c2..57b4bb4 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -3249,6 +3249,12 @@ vte_terminal_child_watch_cb(GPid pid,
                             int status,
                             VteTerminal *terminal)
 {
+	if (terminal == NULL) {
+		/* The child outlived VteTerminal. Do nothing, we're happy that Glib
+		 * read its exit data and hence it's no longer there as zombie. */
+		return;
+	}
+
 	if (pid == terminal->pvt->pty_pid) {
                 GObject *object = G_OBJECT(terminal);
 
@@ -8445,11 +8451,15 @@ vte_terminal_finalize(GObject *object)
 		terminal->pvt->outgoing_conv = VTE_INVALID_CONV;
 	}
 
-	/* Stop listening for child-exited signals. */
+	/* Start listening for child-exited signals and ignore them, so that no zombie child is left behind. */
         if (terminal->pvt->child_watch_source != 0) {
                 g_source_remove (terminal->pvt->child_watch_source);
                 terminal->pvt->child_watch_source = 0;
         }
+        g_child_watch_add_full(G_PRIORITY_HIGH,
+                               terminal->pvt->pty_pid,
+                               (GChildWatchFunc)vte_terminal_child_watch_cb,
+                               NULL, NULL);
 
 	/* Stop processing input. */
 	vte_terminal_stop_processing (terminal);
