X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=2d4341d3b418cd4957b8ab2efc95fbf564f6520e;hb=c5fdc88852bc232e24fb3941ea5d5719b4490a87;hp=a52b208f34b369a6887a59f5ce95da94d48a85d4;hpb=99b72dc0657875cee4a10bf4c855e99a1b1d1f9c;p=ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index a52b208..2d4341d 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include "marker.h" #include "tracer.h" @@ -46,6 +46,11 @@ char consumer_stack[10000]; +/* This should only be accessed by the constructor, before the creation + * of the listener, and then only by the listener. + */ +s64 pidunique = -1LL; + struct list_head blocked_consumers = LIST_HEAD_INIT(blocked_consumers); static struct ustcomm_app ustcomm_app; @@ -58,10 +63,6 @@ struct tracecmd { /* no padding */ /* volatile because shared between the listener and the main thread */ volatile sig_atomic_t buffers_to_export = 0; -//struct listener_arg { -// int pipe_fd; -//}; - struct trctl_msg { /* size: the size of all the fields except size itself */ uint32_t size; @@ -93,6 +94,20 @@ struct blocked_consumer { struct list_head list; }; +static long long make_pidunique(void) +{ + s64 retval; + struct timeval tv; + + gettimeofday(&tv, NULL); + + retval = tv.tv_sec; + retval <<= 32; + retval |= tv.tv_usec; + + return retval; +} + static void print_markers(FILE *fp) { struct marker_iter iter; @@ -102,7 +117,7 @@ static void print_markers(FILE *fp) marker_iter_start(&iter); while(iter.marker) { - fprintf(fp, "marker: %s_%s %d \"%s\"\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format); + fprintf(fp, "marker: %s/%s %d \"%s\"\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format); marker_iter_next(&iter); } unlock_markers(); @@ -682,6 +697,19 @@ void *listener_main(void *p) WARN("could not disable marker; channel=%s, name=%s", channel_name, marker_name); } } + else if(nth_token_is(recvbuf, "get_pidunique", 0) == 1) { + char *reply; + + asprintf(&reply, "%lld", pidunique); + + result = ustcomm_send_reply(&ustcomm_app.server, reply, &src); + if(result) { + ERR("listener: get_pidunique: ustcomm_send_reply failed"); + goto next_cmd; + } + + free(reply); + } // else if(nth_token_is(recvbuf, "get_notifications", 0) == 1) { // struct ltt_trace_struct *trace; // char trace_name[] = "auto"; @@ -740,21 +768,24 @@ void *listener_main(void *p) } } -int have_listener = 0; +volatile sig_atomic_t have_listener = 0; void create_listener(void) { #ifdef USE_CLONE static char listener_stack[16384]; + int result; #else pthread_t thread; #endif - if(have_listener) + if(have_listener) { + WARN("not creating listener because we already had one"); return; + } #ifdef USE_CLONE - result = clone(listener_main, listener_stack+sizeof(listener_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL); + result = clone((int (*)(void *)) listener_main, listener_stack+sizeof(listener_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL); if(result == -1) { perror("clone"); return; @@ -772,12 +803,10 @@ void create_listener(void) void sighandler(int sig) { - static char have_listener = 0; DBG("sighandler"); if(!have_listener) { create_listener(); - have_listener = 1; } } @@ -793,23 +822,6 @@ static int init_socket(void) return ustcomm_init_app(getpid(), &ustcomm_app); } -/* FIXME: reenable this to delete socket file. */ - -#if 0 -static void destroy_socket(void) -{ - int result; - - if(mysocketfile[0] == '\0') - return; - - result = unlink(mysocketfile); - if(result == -1) { - PERROR("unlink"); - } -} -#endif - static int init_signal_handler(void) { /* Attempt to handler SIGIO. If the main program wants to @@ -879,11 +891,16 @@ static void auto_probe_connect(struct marker *m) } -static void __attribute__((constructor(1000))) init() +static void __attribute__((constructor)) init() { int result; char* autoprobe_val = NULL; + /* Assign the pidunique, to be able to differentiate the processes with same + * pid, (before and after an exec). + */ + pidunique = make_pidunique(); + /* Initialize RCU in case the constructor order is not good. */ urcu_init(); @@ -988,13 +1005,15 @@ static void __attribute__((constructor(1000))) init() return; } - inform_consumer_daemon(trace_name); - result = ltt_trace_start(trace_name); if(result < 0) { ERR("ltt_trace_start failed"); return; } + + /* Do this after the trace is started in order to avoid creating confusion + * if the trace fails to start. */ + inform_consumer_daemon(trace_name); } @@ -1005,31 +1024,34 @@ static void __attribute__((constructor(1000))) init() } /* This is only called if we terminate normally, not with an unhandled signal, - * so we cannot rely on it. */ + * so we cannot rely on it. However, for now, LTTV requires that the header of + * the last sub-buffer contain a valid end time for the trace. This is done + * automatically only when the trace is properly stopped. + * + * If the traced program crashed, it is always possible to manually add the + * right value in the header, or to open the trace in text mode. + * + * FIXME: Fix LTTV so it doesn't need this. + */ -/* This destructor probably isn't needed, because ustd can do crash recovery. */ -#if 0 -static void __attribute__((destructor)) fini() +static void destroy_traces(void) { -// int result; + int result; /* if trace running, finish it */ -// DBG("destructor stopping traces"); + DBG("destructor stopping traces"); -// result = ltt_trace_stop("auto"); -// if(result == -1) { -// ERR("ltt_trace_stop error"); -// } -// -// result = ltt_trace_destroy("auto"); -// if(result == -1) { -// ERR("ltt_trace_destroy error"); -// } -// -// destroy_socket(); + result = ltt_trace_stop("auto"); + if(result == -1) { + ERR("ltt_trace_stop error"); + } + + result = ltt_trace_destroy("auto"); + if(result == -1) { + ERR("ltt_trace_destroy error"); + } } -#endif static int trace_recording(void) { @@ -1099,6 +1121,19 @@ static void __attribute__((destructor)) keepalive() } DBG("Finally dying..."); } + + destroy_traces(); + + ustcomm_fini_app(&ustcomm_app); +} + +void ust_potential_exec(void) +{ + trace_mark(ust, potential_exec, MARK_NOARGS); + + DBG("test"); + + keepalive(); } /* Notify ust that there was a fork. This needs to be called inside @@ -1121,6 +1156,8 @@ void ust_fork(void) /* Delete all blocked consumers */ list_for_each_entry(bc, &blocked_consumers, list) { + close(bc->fd_producer); + close(bc->fd_consumer); free(deletable_bc); deletable_bc = bc; list_del(&bc->list); @@ -1133,7 +1170,7 @@ void ust_fork(void) result = ltt_trace_set_type("auto", "ustrelay"); if(result < 0) { ERR("ltt_trace_set_type failed"); - return (void *)1; + return; } ltt_trace_alloc("auto");