From e0966584cf9b291317a89f06df5759306fa2c6c0 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Mon, 6 Jun 2016 12:30:50 +0200
Subject: [PATCH] monitor tracee and local tracer to avoid "dead" processes

this may be removed at some point, it's very brutal. But when you
write some code, it may happen (it "may"!!) that *sometimes* the
code does not work and crashes. In thoses cases I prefer the
local tracer (or the tracee) to go away immediately without even
thinking about it maybe still running in the background.

In case of monitoring (as opposed to debugging) maybe it's preferable
to let the process live its life as it wants.

Time will tell.
---
 common/utils/T/T.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/common/utils/T/T.c b/common/utils/T/T.c
index fca7139991..786b3722ed 100644
--- a/common/utils/T/T.c
+++ b/common/utils/T/T.c
@@ -91,6 +91,23 @@ static void new_thread(void *(*f)(void *), void *data)
 void T_local_tracer_main(int remote_port, int wait_for_tracer,
     int local_socket);
 
+/* We monitor the tracee and the local tracer processes.
+ * When one dies we forcefully kill the other.
+ */
+#include <sys/types.h>
+#include <sys/wait.h>
+static void monitor_and_kill(int child1, int child2)
+{
+  int child;
+  int status;
+
+  child = wait(&status);
+  if (child == -1) perror("wait");
+  kill(child1, SIGKILL);
+  kill(child2, SIGKILL);
+  exit(0);
+}
+
 void T_init(int remote_port, int wait_for_tracer)
 {
   int socket_pair[2];
@@ -98,19 +115,27 @@ void T_init(int remote_port, int wait_for_tracer)
   int T_shm_fd;
   unsigned char *buf;
   int len;
-  int f;
+  int child1, child2;
 
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
     { perror("socketpair"); abort(); }
 
-  f = fork(); if (f == -1) abort();
-  if (f == 0) {
+  /* child1 runs the local tracer and child2 runs the tracee */
+
+  child1 = fork(); if (child1 == -1) abort();
+  if (child1 == 0) {
     close(socket_pair[1]);
     T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]);
     exit(0);
   }
   close(socket_pair[0]);
 
+  child2 = fork(); if (child2 == -1) abort();
+  if (child2 != 0) {
+    close(socket_pair[1]);
+    monitor_and_kill(child1, child2);
+  }
+
   s = socket_pair[1];
   /* wait for first message - initial list of active T events */
   get_message(s);
-- 
GitLab