From 061881255450e798abf887b4e8843a497ce33793 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Tue, 16 Aug 2022 12:01:52 +0200
Subject: [PATCH] T tracer: simplify

- don't call exit() if get_message() fails, simply terminate the thread and
  disable the T tracer
- T_dont_fork disappears, monitor_and_kill() as well, so now it's only 2
  processes: the main (enb/gnb/ue) and the local tracer
---
 common/utils/T/T.c | 119 ++++++++++++++++++++-------------------------
 common/utils/T/T.h |  14 ++----
 2 files changed, 59 insertions(+), 74 deletions(-)

diff --git a/common/utils/T/T.c b/common/utils/T/T.c
index 2d724ffd00..6ba1962d1f 100644
--- a/common/utils/T/T.c
+++ b/common/utils/T/T.c
@@ -8,22 +8,19 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/socket.h>
+#include <sys/types.h>
+#include <signal.h>
 
 #include "common/config/config_userapi.h"
 
-#define QUIT(x) do { \
-    printf("T tracer: QUIT: %s\n", x); \
-    exit(1); \
-  } while (0)
-
 /* array used to activate/disactivate a log */
 static int T_IDs[T_NUMBER_OF_IDS];
 int *T_active = T_IDs;
 
 int T_stdout = 1;
 
-
 static int T_socket;
+static int local_tracer_pid;
 
 /* T_cache
  * - the T macro picks up the head of freelist and marks it busy
@@ -33,63 +30,78 @@ volatile int _T_freelist_head;
 volatile int *T_freelist_head = &_T_freelist_head;
 T_cache_t *T_cache;
 
-static void get_message(int s) {
+#define GET_MESSAGE_FAIL do { \
+    printf("T tracer: get_message failed\n"); \
+    return -1; \
+  } while (0)
+
+/* return -1 if error, 0 if no error */
+static int get_message(int s)
+{
   char t;
   int l;
   int id;
   int is_on;
 
-  if (read(s, &t, 1) != 1) QUIT("get_message fails");
+  if (read(s, &t, 1) != 1) GET_MESSAGE_FAIL;
 
   printf("T tracer: got mess %d\n", t);
 
   switch (t) {
     case 0:
-
       /* toggle all those IDs */
       /* optimze? (too much syscalls) */
-      if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
+      if (read(s, &l, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
 
       while (l) {
-        if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
+        if (read(s, &id, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
 
         T_IDs[id] = 1 - T_IDs[id];
         l--;
       }
-
       break;
-
     case 1:
-
       /* set IDs as given */
       /* optimize? */
-      if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
+      if (read(s, &l, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
 
       id = 0;
 
       while (l) {
         if (read(s, &is_on, sizeof(int)) != sizeof(int))
-          QUIT("get_message fails");
+          GET_MESSAGE_FAIL;
 
         T_IDs[id] = is_on;
         id++;
         l--;
       }
-
       break;
-
     case 2:
       break; /* do nothing, this message is to wait for local tracer */
   }
+
+  return 0;
 }
 
-static void *T_receive_thread(void *_) {
-  while (1) get_message(T_socket);
+static void *T_receive_thread(void *_)
+{
+  int err = 0;
+  while (!err) err = get_message(T_socket);
+
+  printf("T tracer: fatal: T tracer disabled\n");
+
+  shutdown(T_socket, SHUT_RDWR);
+  close(T_socket);
+  kill(local_tracer_pid, SIGKILL);
+
+  /* disable all traces */
+  memset(T_IDs, 0, sizeof(T_IDs));
 
   return NULL;
 }
 
-static void new_thread(void *(*f)(void *), void *data) {
+static void new_thread(void *(*f)(void *), void *data)
+{
   pthread_t t;
   pthread_attr_t att;
 
@@ -118,27 +130,11 @@ static void new_thread(void *(*f)(void *), void *data) {
 void T_local_tracer_main(int remote_port, int wait_for_tracer,
                          int local_socket, void *shm_array);
 
-/* 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 dont_fork) {
+void T_init(int remote_port, int wait_for_tracer)
+{
   int socket_pair[2];
   int s;
-  int child1, child2;
+  int child;
   int i;
 
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) {
@@ -162,47 +158,40 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) {
 
   for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0;
 
-  /* child1 runs the local tracer and child2 (or main) runs the tracee */
-  child1 = fork();
+  /* child runs the local tracer and main runs the tracee */
+  child = fork();
 
-  if (child1 == -1) abort();
+  if (child == -1) abort();
 
-  if (child1 == 0) {
+  if (child == 0) {
     close(socket_pair[1]);
     T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
                         T_cache);
     exit(0);
   }
 
-  close(socket_pair[0]);
+  local_tracer_pid = child;
 
-  if (dont_fork == 0) {
-    child2 = fork();
+  close(socket_pair[0]);
 
-    if (child2 == -1) abort();
+  s = socket_pair[1];
+  T_socket = s;
 
-    if (child2 != 0) {
-      close(socket_pair[1]);
-      munmap(T_cache, T_CACHE_SIZE * sizeof(T_cache_t));
-      monitor_and_kill(child1, child2);
-    }
+  /* wait for first message - initial list of active T events */
+  if (get_message(s) == -1) {
+    kill(local_tracer_pid, SIGKILL);
+    return;
   }
 
-  s = socket_pair[1];
-  /* wait for first message - initial list of active T events */
-  get_message(s);
-  T_socket = s;
   new_thread(T_receive_thread, NULL);
 }
 
-void T_Config_Init(void) {
-  int T_port=TTRACER_DEFAULT_PORTNUM; /* by default we wait for the tracer */
-  int T_nowait=0;                     /* default port to listen to to wait for the tracer */
-  int T_dont_fork=0;                  /* default is to fork, see 'T_init' to understand */
+void T_Config_Init(void)
+{
+  int T_port = TTRACER_DEFAULT_PORTNUM;
+  int T_nowait = 0;
   paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC;
-  /* for a cleaner config file, TTracer params should be defined in a
-   * specific section...
-   */
+
   config_get(ttraceparams,
              sizeof(ttraceparams) / sizeof(paramdef_t),
              TTRACER_CONFIG_PREFIX);
@@ -217,5 +206,5 @@ void T_Config_Init(void) {
   }
 
   if (T_stdout == 0 || T_stdout == 2)
-    T_init(T_port, 1-T_nowait, T_dont_fork);
+    T_init(T_port, 1-T_nowait);
 }
diff --git a/common/utils/T/T.h b/common/utils/T/T.h
index df1e95d2df..dd698906c8 100644
--- a/common/utils/T/T.h
+++ b/common/utils/T/T.h
@@ -15,8 +15,8 @@
 #include "T_IDs.h"
 
 #define T_ACTIVE_STDOUT  2
-/* known type - this is where you add new types */
 
+/* known type - this is where you add new types */
 #define T_INT(x) int, (x)
 #define T_FLOAT(x) float, (x)
 #define T_BUFFER(x, len) buffer, ((T_buffer){addr:(x), length:(len)})
@@ -111,6 +111,7 @@ typedef struct {
 extern volatile int *T_freelist_head;
 extern T_cache_t *T_cache;
 extern int *T_active;
+
 #define T_GET_SLOT \
   T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01);
 
@@ -559,14 +560,12 @@ extern int *T_active;
     } \
   } while (0)
 
-
 #define CONFIG_HLP_TPORT         "tracer port\n"
 #define CONFIG_HLP_NOTWAIT       "don't wait for tracer, start immediately\n"
-#define CONFIG_HLP_TNOFORK       "to ease debugging with gdb\n"
 #define CONFIG_HLP_STDOUT        "print log messges on console\n"
 
-
 #define TTRACER_CONFIG_PREFIX   "TTracer"
+
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            configuration parameters for TTRACE utility                                                          */
 /*   optname                     helpstr                paramflags           XXXptr           defXXXval                         type       numelt  */
@@ -575,15 +574,12 @@ extern int *T_active;
 #define CMDLINE_TTRACEPARAMS_DESC {  \
     {"T_port",                     CONFIG_HLP_TPORT,      0,                iptr:&T_port,        defintval:TTRACER_DEFAULT_PORTNUM, TYPE_INT,   0},\
     {"T_nowait",                   CONFIG_HLP_NOTWAIT,    PARAMFLAG_BOOL,   iptr:&T_nowait,      defintval:0,                       TYPE_INT,   0},\
-    {"T_dont_fork",                CONFIG_HLP_TNOFORK,    PARAMFLAG_BOOL,   iptr:&T_dont_fork,   defintval:0,                       TYPE_INT,   0},\
     {"T_stdout",                   CONFIG_HLP_STDOUT,     0,                iptr:&T_stdout,      defintval:1,                       TYPE_INT,   0},\
   }
 
-
-
-/* log on stdout */
-void T_init(int remote_port, int wait_for_tracer, int dont_fork);
+void T_init(int remote_port, int wait_for_tracer);
 void T_Config_Init(void);
+
 #else /* T_TRACER */
 
 /* if T_TRACER is not defined or is 0, the T is deactivated */
-- 
2.26.2