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 #include #include +#include +#include #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 -#include -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); } + local_tracer_pid = child; + close(socket_pair[0]); - if (dont_fork == 0) { - child2 = fork(); + s = socket_pair[1]; + T_socket = s; - if (child2 == -1) abort(); - - 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 */