#define _GNU_SOURCE
#define LTT_TRACE
#define LTT_TRACE_FAST
-#include <sys/types.h>
-#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
#include <string.h>
-#include <sys/mman.h>
#include <signal.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <errno.h>
#include <sys/param.h>
#include <sys/time.h>
-#include <errno.h>
-
-#include <asm/atomic.h>
-#include <asm/timex.h> //for get_cycles()
-
-_syscall0(pid_t,gettid)
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/syscall.h>
#include <ltt/ltt-usertrace.h>
+#define gettid() syscall(__NR_gettid)
+
#ifdef LTT_SHOW_DEBUG
#define dbg_printf(...) printf(__VA_ARGS__)
#else
static pid_t traced_pid = 0;
static pid_t traced_tid = 0;
static int parent_exited = 0;
+static int fd_process = -1;
+static char outfile_name[PATH_MAX];
+static char identifier_name[PATH_MAX];
/* signal handling */
static void handler_sigusr1(int signo)
index in the buffer being the one which will win this loop. */
/* If the buffer is not in overwrite mode, pushing the reader only
happen if a sub-buffer is corrupted */
- if((SUBBUF_TRUNC(offset_end, ltt_buf)
+ if((SUBBUF_TRUNC(offset_end-1, ltt_buf)
- SUBBUF_TRUNC(consumed_old, ltt_buf))
>= ltt_buf->alloc_size)
consumed_new = SUBBUF_ALIGN(consumed_old, ltt_buf);
}
+
+static int open_output_files(void)
+{
+ int ret;
+ int fd;
+ /* Open output files */
+ umask(00000);
+ ret = mkdir(LTT_USERTRACE_ROOT, 0777);
+ if(ret < 0 && errno != EEXIST) {
+ perror("LTT Error in creating output (mkdir)");
+ exit(-1);
+ }
+ ret = chdir(LTT_USERTRACE_ROOT);
+ if(ret < 0) {
+ perror("LTT Error in creating output (chdir)");
+ exit(-1);
+ }
+ snprintf(identifier_name, PATH_MAX-1, "%lu.%lu.%llu",
+ traced_tid, traced_pid, get_cycles());
+ snprintf(outfile_name, PATH_MAX-1, "process-%s", identifier_name);
+
+#ifndef LTT_NULL_OUTPUT_TEST
+ fd = creat(outfile_name, 0644);
+#else
+ /* NULL test */
+ ret = symlink("/dev/null", outfile_name);
+ if(ret < 0) {
+ perror("error in symlink");
+ exit(-1);
+ }
+ fd = open(outfile_name, O_WRONLY);
+ if(fd_process < 0) {
+ perror("Error in open");
+ exit(-1);
+ }
+#endif //LTT_NULL_OUTPUT_TEST
+ return fd;
+}
+
static inline int ltt_buffer_get(struct ltt_buf *ltt_buf,
unsigned int *offset)
{
* It can also happen if this is a buffer we never got. */
return -EIO;
} else {
+ if(traced_pid == 0 || parent_exited) return 0;
+
ret = sem_post(<t_buf->writer_sem);
if(ret < 0) {
printf("error in sem_post");
}
}
+ return ret;
}
static int read_subbuffer(struct ltt_buf *ltt_buf, int fd)
if(err != -EAGAIN) dbg_printf("LTT Reserving sub buffer failed\n");
goto get_error;
}
+ if(fd_process == -1) {
+ fd_process = fd = open_output_files();
+ }
err = TEMP_FAILURE_RETRY(write(fd,
ltt_buf->start
{
struct sigaction act;
int ret;
- int fd_process;
- char outfile_name[PATH_MAX];
- char identifier_name[PATH_MAX];
traced_pid = l_traced_pid;
traced_tid = l_traced_tid;
alarm(3);
- /* Open output files */
- umask(00000);
- ret = mkdir(LTT_USERTRACE_ROOT, 0777);
- if(ret < 0 && errno != EEXIST) {
- perror("LTT Error in creating output (mkdir)");
- exit(-1);
- }
- ret = chdir(LTT_USERTRACE_ROOT);
- if(ret < 0) {
- perror("LTT Error in creating output (chdir)");
- exit(-1);
- }
- snprintf(identifier_name, PATH_MAX-1, "%lu.%lu.%llu",
- traced_tid, traced_pid, get_cycles());
- snprintf(outfile_name, PATH_MAX-1, "process-%s", identifier_name);
-
- /* Wait for the first signal before creating files */
- ret = sigsuspend(&oldset);
- if(ret != -1) {
- perror("LTT Error in sigsuspend\n");
- }
- if((traced_pid == 0) || parent_exited) goto dead_parent;
-
-#ifndef LTT_NULL_OUTPUT_TEST
- fd_process = creat(outfile_name, 0644);
-#else
- /* NULL test */
- ret = symlink("/dev/null", outfile_name);
- if(ret < 0) {
- perror("error in symlink");
- }
- fd_process = open(outfile_name, O_WRONLY);
- if(fd_process < 0) {
- perror("Error in open");
- }
-#endif //LTT_NULL_OUTPUT_TEST
-
while(1) {
+ ret = sigsuspend(&oldset);
+ if(ret != -1) {
+ perror("LTT Error in sigsuspend\n");
+ }
if(traced_pid == 0) break; /* parent died */
if(parent_exited) break;
dbg_printf("LTT Doing a buffer switch read. pid is : %lu\n", getpid());
do {
ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
} while(ret == 0);
-
- ret = sigsuspend(&oldset);
- if(ret != -1) {
- perror("LTT Error in sigsuspend\n");
- }
}
-dead_parent:
/* The parent thread is dead and we have finished with the buffer */
/* Buffer force switch (flush). Using FLUSH instead of ACTIVE because we know
ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
} while(ret == 0);
-
- close(fd_process);
+ if(fd_process != -1)
+ close(fd_process);
ret = sem_destroy(&shared_trace_info->channel.process.writer_sem);
if(ret < 0) {