The ust-consumerd gets shutdown by the SIGTERM signal and a number of
places in the ust-consumerd did not properly deal with the case where
a system call returns EINTR in errno as a result of a signal to the
process. The failure to handle EINTR properly was leading to some
data corruption in the buffer code and causing some random "victim"
crashes in lowlevel.c
The way all the offending functions were tracked down was to
temporarily add an abort() in the SIGTERM signal handler. Then it was
a matter of looking at what threads were blocked on system calls at
the time outside of the thread that received the signal.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Nils Carlson <nils.carlson@ericsson.com>
DBG("App died while being traced");
finish_consuming_dead_subbuffer(instance->callbacks, buf);
break;
DBG("App died while being traced");
finish_consuming_dead_subbuffer(instance->callbacks, buf);
break;
+ } else if (read_result == -1 && errno == EINTR) {
+ continue;
}
if(instance->callbacks->on_read_subbuffer)
}
if(instance->callbacks->on_read_subbuffer)
result = fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(result == -1) {
result = fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(result == -1) {
+ if (errno == EINTR)
+ goto socket_again;
PERROR("socket");
return 1;
}
PERROR("socket");
return 1;
}
strncpy(addr.sun_path, instance->sock_path, UNIX_PATH_MAX);
addr.sun_path[UNIX_PATH_MAX-1] = '\0';
strncpy(addr.sun_path, instance->sock_path, UNIX_PATH_MAX);
addr.sun_path[UNIX_PATH_MAX-1] = '\0';
result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
if(result == -1) {
result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
if(result == -1) {
+ if (errno == EINTR)
+ goto connect_again;
- while(bytes != sizeof(msg))
- bytes += send(fd, msg, sizeof(msg), 0);
+ while(bytes != sizeof(msg)) {
+ int inc = send(fd, msg, sizeof(msg), 0);
+ if (inc < 0 && errno != EINTR)
+ break;
+ else
+ bytes += inc;
+ }
trace_path, buf->pid, buf->pidunique, buf->name);
return 1;
}
trace_path, buf->pid, buf->pidunique, buf->name);
return 1;
}
result = fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 00600);
result = fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 00600);
+ if (result == -1 && errno == EINTR)
+ goto again;
+
if(result == -1) {
PERROR("open");
ERR("failed opening trace file %s", tmp);
if(result == -1) {
PERROR("open");
ERR("failed opening trace file %s", tmp);
int on_close_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
{
struct buffer_info_local *buf_local = buf->user_data;
int on_close_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
{
struct buffer_info_local *buf_local = buf->user_data;
- int result = close(buf_local->file_fd);
+ int result;
+
+again:
+ result = close(buf_local->file_fd);
+ if (result == -1 && errno == EINTR)
+ goto again;
free(buf_local);
if(result == -1) {
PERROR("close");
free(buf_local);
if(result == -1) {
PERROR("close");