X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ustd%2Fustd.c;h=8a1f4d60c2df6397cbccdd5af6d5b54a8849023f;hb=5609732975848531a05afa18285e46949ae78eec;hp=8eeb62ba361aa0a7696b7540a827fb24b6cafb4e;hpb=750f9da42a4d6e09b068ca959977707b20c98f36;p=ust.git diff --git a/ustd/ustd.c b/ustd/ustd.c index 8eeb62b..8a1f4d6 100644 --- a/ustd/ustd.c +++ b/ustd/ustd.c @@ -59,7 +59,7 @@ char *pidfile = NULL; int active_buffers = 0; pthread_mutex_t active_buffers_mutex = PTHREAD_MUTEX_INITIALIZER; /* Whether a request to end the program was received. */ -sig_atomic_t terminate_req = 0; +volatile sig_atomic_t terminate_req = 0; int get_subbuffer(struct buffer_info *buf) { @@ -71,7 +71,7 @@ int get_subbuffer(struct buffer_info *buf) asprintf(&send_msg, "get_subbuffer %s", buf->name); result = ustcomm_send_request(&buf->conn, send_msg, &received_msg); - if((result == -1 && errno == EPIPE) || result == 0) { + if((result == -1 && (errno == ECONNRESET || errno == EPIPE)) || result == 0) { DBG("app died while being traced"); retval = GET_SUBBUF_DIED; goto end; @@ -99,8 +99,8 @@ int get_subbuffer(struct buffer_info *buf) goto end_rep; } else if(!strcmp(received_msg, "NOTFOUND")) { - WARN("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name); - retval = GET_SUBBUF_DONE; + DBG("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name); + retval = GET_SUBBUF_DIED; goto end_rep; } else { @@ -131,7 +131,7 @@ int put_subbuffer(struct buffer_info *buf) asprintf(&send_msg, "put_subbuffer %s %ld", buf->name, buf->consumed_old); result = ustcomm_send_request(&buf->conn, send_msg, &received_msg); - if(result < 0 && errno == ECONNRESET) { + if(result < 0 && (errno == ECONNRESET || errno == EPIPE)) { retval = PUT_SUBBUF_DIED; goto end; } @@ -160,7 +160,7 @@ int put_subbuffer(struct buffer_info *buf) retval = PUT_SUBBUF_OK; } else if(!strcmp(received_msg, "NOTFOUND")) { - WARN("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name); + DBG("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name); /* However, maybe this was not the last subbuffer. So * we return the program died. */ @@ -465,7 +465,6 @@ int write_current_subbuffer(struct buffer_info *buf) result = patient_write(buf->file_fd, subbuf_mem, cur_sb_size); if(result == -1) { PERROR("write"); - /* FIXME: maybe drop this trace */ return -1; } @@ -495,8 +494,10 @@ int consumer_loop(struct buffer_info *buf) } /* write data to file */ - write_current_subbuffer(buf); - /* FIXME: handle return value? */ + result = write_current_subbuffer(buf); + if(result == -1) { + ERR("Failed writing a subbuffer to file (channel=%s). Dropping this buffer.", buf->name); + } /* put the subbuffer */ result = put_subbuffer(buf); @@ -509,7 +510,7 @@ int consumer_loop(struct buffer_info *buf) break; } else if(result == PUT_SUBBUF_DIED) { - WARN("application died while putting subbuffer"); + DBG("application died while putting subbuffer"); /* Skip the first subbuffer. We are not sure it is trustable * because the put_subbuffer() did not complete. */ @@ -548,9 +549,33 @@ void *consumer_thread(void *arg) { struct buffer_info *buf = (struct buffer_info *) arg; struct consumer_thread_args *args = (struct consumer_thread_args *) arg; + int result; + sigset_t sigset; DBG("GOT ARGS: pid %d bufname %s", args->pid, args->bufname); + /* Block signals that should be handled by the main thread. */ + result = sigemptyset(&sigset); + if(result == -1) { + PERROR("sigemptyset"); + goto end; + } + result = sigaddset(&sigset, SIGTERM); + if(result == -1) { + PERROR("sigaddset"); + goto end; + } + result = sigaddset(&sigset, SIGINT); + if(result == -1) { + PERROR("sigaddset"); + goto end; + } + result = sigprocmask(SIG_BLOCK, &sigset, NULL); + if(result == -1) { + PERROR("sigprocmask"); + goto end; + } + buf = connect_buffer(args->pid, args->bufname); if(buf == NULL) { ERR("failed to connect to buffer"); @@ -559,11 +584,10 @@ void *consumer_thread(void *arg) consumer_loop(buf); - free(args->bufname); destroy_buffer(buf); end: - /* bufname is free'd in free_buffer() */ + free((void *)args->bufname); free(args); return NULL; } @@ -693,6 +717,7 @@ int start_ustd(int fd) int result; sigset_t sigset; struct sigaction sa; + int timeout = -1; result = sigemptyset(&sigset); if(result == -1) { @@ -701,7 +726,7 @@ int start_ustd(int fd) } sa.sa_handler = sigterm_handler; sa.sa_mask = sigset; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; result = sigaction(SIGTERM, &sa, NULL); if(result == -1) { PERROR("sigaction"); @@ -768,12 +793,15 @@ int start_ustd(int fd) char *recvbuf; /* check for requests on our public socket */ - result = ustcomm_ustd_recv_message(&ustd, &recvbuf, NULL, 100); - if(result == -1) { + result = ustcomm_ustd_recv_message(&ustd, &recvbuf, NULL, timeout); + if(result == -1 && errno == EINTR) { + /* Caught signal */ + } + else if(result == -1) { ERR("error in ustcomm_ustd_recv_message"); goto loop_end; } - if(result > 0) { + else if(result > 0) { if(!strncmp(recvbuf, "collect", 7)) { pid_t pid; char *bufname; @@ -810,6 +838,7 @@ int start_ustd(int fd) break; } pthread_mutex_unlock(&active_buffers_mutex); + timeout = 100; } }