From 62e026c68231e6d20c75d2a4e3df5ec6f2fcf9e9 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 10 Aug 2012 15:45:48 -0400 Subject: [PATCH 01/16] fix warnings Signed-off-by: Julien Desfossez --- src/lttngtop.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index fd23e74..6f4fd33 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -849,7 +849,7 @@ void *live_consume() fprintf(stderr,"OPENING TRACE\n"); if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); - return; + return NULL; } metadata_ready = 1; metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); @@ -859,6 +859,10 @@ void *live_consume() bt_ctx = bt_context_create(); ret = bt_context_add_trace(bt_ctx, NULL, "ctf", lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); + if (ret < 0) { + printf("Error adding trace\n"); + return NULL; + } trace_opened = 1; } iter_trace(bt_ctx); @@ -999,7 +1003,7 @@ void *setup_live_tracing() //init_lttngtop(); end: - return ret; + return NULL; } int main(int argc, char **argv) -- 2.34.1 From 6112d0d4436698a4e5625b89309d7ac8864ebef1 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 14 Aug 2012 10:45:50 -0400 Subject: [PATCH 02/16] we can now read subbuff in mmap and print timestamps Signed-off-by: Julien Desfossez --- src/lttngtop.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index 6f4fd33..bae4fad 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -132,6 +132,45 @@ void *ncurses_display(void *p) } } +/* FIXME : TMP */ +struct tm ts_format_timestamp(uint64_t timestamp) +{ + struct tm tm; + uint64_t ts_sec = 0, ts_nsec; + time_t time_s; + + ts_nsec = timestamp; + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + + time_s = (time_t) ts_sec; + + localtime_r(&time_s, &tm); + + return tm; +} + +/* + * hook on each event to check the timestamp and refresh the display if + * necessary + */ +enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_data) +{ + unsigned long timestamp; + struct tm start; + uint64_t ts_nsec_start, ts_nsec_end; + + + timestamp = bt_ctf_get_timestamp(call_data); + + start = ts_format_timestamp(timestamp); + ts_nsec_start = timestamp % NSEC_PER_SEC; + +// printf("%02d:%02d:%02d.%09" PRIu64 "\n", start.tm_hour, start.tm_min, start.tm_sec, ts_nsec_start); + + return BT_CB_OK; +} + /* * hook on each event to check the timestamp and refresh the display if * necessary @@ -390,6 +429,11 @@ void iter_trace(struct bt_context *bt_ctx) begin_pos.type = BT_SEEK_BEGIN; iter = bt_ctf_iter_create(bt_ctx, &begin_pos, NULL); + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + print_timestamp, + NULL, NULL, NULL); + +#if 0 /* at each event check if we need to refresh */ bt_ctf_iter_add_callback(iter, 0, NULL, 0, check_timestamp, @@ -434,7 +478,7 @@ void iter_trace(struct bt_context *bt_ctx) "lttng_statedump_file_descriptor"), NULL, 0, handle_statedump_file_descriptor, NULL, NULL, NULL); - +#endif while ((event = bt_ctf_iter_read_event(iter)) != NULL) { ret = bt_iter_next(bt_ctf_get_iter(iter)); if (ret < 0) @@ -824,7 +868,8 @@ int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) } g_ptr_array_add(lttng_consumer_stream_array, kconsumerd_fd); - ret = 0; + /* keep mmap FDs internally */ + ret = 1; } else { consumerd_metadata = helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd); sessiond_metadata = helper_get_lttng_consumer_stream_key(kconsumerd_fd); -- 2.34.1 From 71c74ca6971b2ed2b259660ecd3734f4650784fc Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 15 Aug 2012 19:09:10 -0400 Subject: [PATCH 03/16] working textdump Signed-off-by: Julien Desfossez --- src/lttngtop.c | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index bae4fad..a042ceb 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -166,7 +166,9 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat start = ts_format_timestamp(timestamp); ts_nsec_start = timestamp % NSEC_PER_SEC; -// printf("%02d:%02d:%02d.%09" PRIu64 "\n", start.tm_hour, start.tm_min, start.tm_sec, ts_nsec_start); + printf("%02d:%02d:%02d.%09" PRIu64 " %s\n", start.tm_hour, + start.tm_min, start.tm_sec, ts_nsec_start, + bt_ctf_event_name(call_data)); return BT_CB_OK; } @@ -885,34 +887,30 @@ void *live_consume() struct bt_context *bt_ctx = NULL; int ret; - while (1) { -// dump_snapshot(); - - if (!metadata_ready) { - fprintf(stderr, "BLOCKING BEFORE METADATA\n"); - sem_wait(&metadata_available); - fprintf(stderr,"OPENING TRACE\n"); - if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { - fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); - return NULL; - } - metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); + if (!metadata_ready) { + fprintf(stderr, "BLOCKING BEFORE METADATA\n"); + sem_wait(&metadata_available); + fprintf(stderr,"OPENING TRACE\n"); + if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { + fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); + return NULL; } + metadata_ready = 1; + metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); + } - if (!trace_opened) { - bt_ctx = bt_context_create(); - ret = bt_context_add_trace(bt_ctx, NULL, "ctf", - lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); - if (ret < 0) { - printf("Error adding trace\n"); - return NULL; - } - trace_opened = 1; + if (!trace_opened) { + bt_ctx = bt_context_create(); + ret = bt_context_add_trace(bt_ctx, NULL, "ctf", + lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); + if (ret < 0) { + printf("Error adding trace\n"); + return NULL; } - iter_trace(bt_ctx); - sleep(1); + trace_opened = 1; } + iter_trace(bt_ctx); + sleep(1); } int setup_consumer(char *command_sock_path, pthread_t *threads, @@ -977,6 +975,7 @@ void *setup_live_tracing() ret = system("rm -rf /tmp/livesession"); + lttng_destroy_session("test"); if ((ret = lttng_create_session("test", "/tmp/livesession")) < 0) { fprintf(stderr,"error creating the session : %s\n", helper_lttcomm_get_readable_code(ret)); @@ -1068,7 +1067,7 @@ int main(int argc, char **argv) if (!opt_input_path) { printf("live tracing enabled\n"); pthread_create(&live_trace_thread, NULL, setup_live_tracing, (void *) NULL); - sleep(20); + sleep(2000); printf("STOPPING\n"); lttng_stop_tracing("test"); printf("DESTROYING\n"); -- 2.34.1 From b520ab458ea26829d00fca98f4bbb90309fd30df Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 15 Aug 2012 19:18:49 -0400 Subject: [PATCH 04/16] cleanup, live textdump working Signed-off-by: Julien Desfossez --- src/common.c | 17 ++++++ src/common.h | 2 + src/cursesdisplay.c | 17 ------ src/lttngtop.c | 143 ++++---------------------------------------- 4 files changed, 29 insertions(+), 150 deletions(-) diff --git a/src/common.c b/src/common.c index f741a29..bff5b00 100644 --- a/src/common.c +++ b/src/common.c @@ -529,3 +529,20 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, error: return BT_CB_ERROR_STOP; } + +struct tm format_timestamp(uint64_t timestamp) +{ + struct tm tm; + uint64_t ts_sec = 0, ts_nsec; + time_t time_s; + + ts_nsec = timestamp; + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + + time_s = (time_t) ts_sec; + + localtime_r(&time_s, &tm); + + return tm; +} diff --git a/src/common.h b/src/common.h index fd9a367..3738331 100644 --- a/src/common.h +++ b/src/common.h @@ -66,4 +66,6 @@ char *get_context_comm(const struct bt_ctf_event *event); enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, void *private_data); +struct tm format_timestamp(uint64_t timestamp); + #endif /* _COMMON_H */ diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index 8c1a3ba..25fe1f9 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -302,23 +302,6 @@ void basic_header() wrefresh(header); } -struct tm format_timestamp(uint64_t timestamp) -{ - struct tm tm; - uint64_t ts_sec = 0, ts_nsec; - time_t time_s; - - ts_nsec = timestamp; - ts_sec += ts_nsec / NSEC_PER_SEC; - ts_nsec = ts_nsec % NSEC_PER_SEC; - - time_s = (time_t) ts_sec; - - localtime_r(&time_s, &tm); - - return tm; -} - static void scale_unit(uint64_t bytes, char *ret) { if (bytes >= 1000000000) diff --git a/src/lttngtop.c b/src/lttngtop.c index a042ceb..15d44e0 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -132,24 +132,6 @@ void *ncurses_display(void *p) } } -/* FIXME : TMP */ -struct tm ts_format_timestamp(uint64_t timestamp) -{ - struct tm tm; - uint64_t ts_sec = 0, ts_nsec; - time_t time_s; - - ts_nsec = timestamp; - ts_sec += ts_nsec / NSEC_PER_SEC; - ts_nsec = ts_nsec % NSEC_PER_SEC; - - time_s = (time_t) ts_sec; - - localtime_r(&time_s, &tm); - - return tm; -} - /* * hook on each event to check the timestamp and refresh the display if * necessary @@ -158,12 +140,12 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat { unsigned long timestamp; struct tm start; - uint64_t ts_nsec_start, ts_nsec_end; + uint64_t ts_nsec_start; timestamp = bt_ctf_get_timestamp(call_data); - start = ts_format_timestamp(timestamp); + start = format_timestamp(timestamp); ts_nsec_start = timestamp % NSEC_PER_SEC; printf("%02d:%02d:%02d.%09" PRIu64 " %s\n", start.tm_hour, @@ -690,84 +672,6 @@ int check_requirements(struct bt_context *ctx) return ret; } -void dump_snapshot() -{ -#if 0 - struct lttng_consumer_stream *iter; - unsigned long spos; - struct mmap_stream *new_snapshot; - - int ret = 0; - int i; - /* - * try lock mutex ressource courante (overrun) - * if fail : overrun - * stop trace (flush implicite avant stop) - * lttng_consumer_take_snapshot - * read timestamp packet end (use time as end pos) - * - stream_packet_context - * - reculer de 1 subbuf : pos - max_subbuff_size - * - * - position de fin (take_snapshot) - * - mov_pos_slow ( fin - max_subbuff_size) lire timestamp packet end - * - prend min(end) (activité sur tous les streams) - * - * start trace - * unlock mutex - */ - - helper_kernctl_buffer_flush(consumerd_metadata); - for (i = 0; i < lttng_consumer_stream_array->len; i++) { - iter = g_ptr_array_index(lttng_consumer_stream_array, i); - helper_kernctl_buffer_flush(helper_get_lttng_consumer_stream_wait_fd(iter)); - printf("Taking snapshot of fd : %d\n", helper_get_lttng_consumer_stream_wait_fd(iter)); - ret = helper_lttng_consumer_take_snapshot(ctx, iter); - if (ret != 0) { - ret = errno; - perror("lttng_consumer_take_snapshots"); - goto end; - } - } - for (i = 0; i < lttng_consumer_stream_array->len; i++) { - iter = g_ptr_array_index(lttng_consumer_stream_array, i); - ret = helper_lttng_consumer_get_produced_snapshot(ctx, iter, &spos); - if (ret != 0) { - ret = errno; - perror("helper_lttng_consumer_get_produced_snapshot"); - goto end; - } - while (helper_get_lttng_consumer_stream_wait_last_pos(iter) < spos) { - new_snapshot = g_new0(struct mmap_stream, 1); - new_snapshot->fd = helper_get_lttng_consumer_stream_wait_fd(iter); - new_snapshot->last_pos = helper_get_lttng_consumer_stream_wait_last_pos(iter); - fprintf(stderr,"ADDING AVAILABLE SNAPSHOT ON FD %d AT POSITION %lu\n", - new_snapshot->fd, - new_snapshot->last_pos); - g_ptr_array_add(available_snapshots, new_snapshot); - helper_set_lttng_consumer_stream_wait_last_pos(iter, - helper_get_lttng_consumer_stream_wait_last_pos(iter) + - helper_get_lttng_consumer_stream_chan_max_sb_size(iter)); - } - } - - if (!metadata_ready) { - fprintf(stderr, "BLOCKING BEFORE METADATA\n"); - sem_wait(&metadata_available); - fprintf(stderr,"OPENING TRACE\n"); - if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { - fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); - return; - } - metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); - } - - -end: - return; -#endif -} - ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, struct lttng_consumer_local_data *ctx) { @@ -778,7 +682,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, if (helper_get_lttng_consumer_stream_output(kconsumerd_fd) == LTTNG_EVENT_SPLICE) { /* Get the next subbuffer */ - printf("get_next : %d\n", infd); err = helper_kernctl_get_next_subbuf(infd); if (err != 0) { ret = errno; @@ -793,7 +696,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, perror("Getting sub-buffer len failed."); goto end; } - printf("len : %ld\n", len); /* splice the subbuffer to the tracefile */ ret = helper_lttng_consumer_on_read_subbuffer_splice(ctx, kconsumerd_fd, len); @@ -804,8 +706,6 @@ ssize_t read_subbuffer(struct lttng_consumer_stream *kconsumerd_fd, */ fprintf(stderr,"Error splicing to tracefile\n"); } - printf("ret : %ld\n", ret); - printf("put_next : %d\n", infd); err = helper_kernctl_put_next_subbuf(infd); if (err != 0) { ret = errno; @@ -831,8 +731,7 @@ int on_update_fd(int key, uint32_t state) int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) { int ret; - struct mmap_stream *new_info; - size_t tmp_mmap_len; + struct mmap_stream *new_mmap_stream; /* Opening the tracefile in write mode */ if (helper_get_lttng_consumer_stream_path_name(kconsumerd_fd) != NULL) { @@ -846,28 +745,10 @@ int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) } if (helper_get_lttng_consumer_stream_output(kconsumerd_fd) == LTTNG_EVENT_MMAP) { - new_info = malloc(sizeof(struct mmap_stream)); - new_info->fd = helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd); - bt_list_add(&new_info->list, &mmap_list.head); - - /* get the len of the mmap region */ - ret = helper_kernctl_get_mmap_len(helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd), - &tmp_mmap_len); - if (ret != 0) { - ret = errno; - perror("helper_kernctl_get_mmap_len"); - goto end; - } - helper_set_lttng_consumer_stream_mmap_len(kconsumerd_fd, tmp_mmap_len); - - helper_set_lttng_consumer_stream_mmap_base(kconsumerd_fd, - mmap(NULL, helper_get_lttng_consumer_stream_mmap_len(kconsumerd_fd), - PROT_READ, MAP_PRIVATE, helper_get_lttng_consumer_stream_wait_fd(kconsumerd_fd), 0)); - if (helper_get_lttng_consumer_stream_mmap_base(kconsumerd_fd) == MAP_FAILED) { - perror("Error mmaping"); - ret = -1; - goto end; - } + new_mmap_stream = malloc(sizeof(struct mmap_stream)); + new_mmap_stream->fd = helper_get_lttng_consumer_stream_wait_fd( + kconsumerd_fd); + bt_list_add(&new_mmap_stream->list, &mmap_list.head); g_ptr_array_add(lttng_consumer_stream_array, kconsumerd_fd); /* keep mmap FDs internally */ @@ -888,11 +769,9 @@ void *live_consume() int ret; if (!metadata_ready) { - fprintf(stderr, "BLOCKING BEFORE METADATA\n"); sem_wait(&metadata_available); - fprintf(stderr,"OPENING TRACE\n"); if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { - fprintf(stderr,"NO METADATA FILE, SKIPPING\n"); + fprintf(stderr,"no metadata\n"); return NULL; } metadata_ready = 1; @@ -910,7 +789,8 @@ void *live_consume() trace_opened = 1; } iter_trace(bt_ctx); - sleep(1); + + return NULL; } int setup_consumer(char *command_sock_path, pthread_t *threads, @@ -1039,8 +919,6 @@ void *setup_live_tracing() goto end; } -// pthread_cancel(live_trace_thread); - /* block until metadata is ready */ sem_init(&metadata_available, 0, 0); @@ -1065,7 +943,6 @@ int main(int argc, char **argv) } if (!opt_input_path) { - printf("live tracing enabled\n"); pthread_create(&live_trace_thread, NULL, setup_live_tracing, (void *) NULL); sleep(2000); printf("STOPPING\n"); -- 2.34.1 From b872c906dbdf4780d0bad7bb01b0fa74af530d68 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 15 Aug 2012 19:26:05 -0400 Subject: [PATCH 05/16] all events Signed-off-by: Julien Desfossez --- src/lttngtop.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index 15d44e0..2857d57 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -883,16 +883,18 @@ void *setup_live_tracing() chan.attr.output = LTTNG_EVENT_MMAP; if ((ret = lttng_enable_channel(handle, &chan)) < 0) { - fprintf(stderr,"error creating channel : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error creating channel : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } - sprintf(ev.name, "sched_switch"); + memset(&ev, '\0', sizeof(struct lttng_event)); + //sprintf(ev.name, "sched_switch"); ev.type = LTTNG_EVENT_TRACEPOINT; - //if ((ret = lttng_enable_event(handle, NULL, channel_name)) < 0) { if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { - fprintf(stderr,"error enabling event : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error enabling event : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } @@ -906,7 +908,8 @@ void *setup_live_tracing() lttng_add_context(handle, &kctxtid, NULL, NULL); if ((ret = lttng_start_tracing("test")) < 0) { - fprintf(stderr,"error starting tracing : %s\n", helper_lttcomm_get_readable_code(ret)); + fprintf(stderr,"error starting tracing : %s\n", + helper_lttcomm_get_readable_code(ret)); goto end; } -- 2.34.1 From 6777529d08ef971ec423bf62b69fab662fe4040a Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 15 Aug 2012 19:51:33 -0400 Subject: [PATCH 06/16] cleanup threads scheme and textdump option Signed-off-by: Julien Desfossez --- src/lttngtop.c | 146 ++++++++++++++++++++++++------------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index 2857d57..7c0ec53 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -51,18 +51,16 @@ #define DEFAULT_FILE_ARRAY_SIZE 1 const char *opt_input_path; +int opt_textdump; struct lttngtop *copy; pthread_t display_thread; pthread_t timer_thread; -pthread_t live_trace_thread; unsigned long refresh_display = 1 * NSEC_PER_SEC; unsigned long last_display_update = 0; int quit = 0; -/* LIVE */ -pthread_t thread_live_consume; /* list of FDs available for being read with snapshots */ struct mmap_stream_list mmap_list; GPtrArray *lttng_consumer_stream_array; @@ -78,15 +76,13 @@ int metadata_ready = 0; enum { OPT_NONE = 0, OPT_HELP, - OPT_LIST, - OPT_VERBOSE, - OPT_DEBUG, - OPT_NAMES, + OPT_TEXTDUMP, }; static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL }, + { "textdump", 't', POPT_ARG_NONE, NULL, OPT_TEXTDUMP, NULL, NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL }, }; @@ -388,6 +384,9 @@ static int parse_options(int argc, char **argv) usage(stdout); ret = 1; /* exit cleanly */ goto end; + case OPT_TEXTDUMP: + opt_textdump = 1; + goto end; default: ret = -EINVAL; goto end; @@ -413,56 +412,57 @@ void iter_trace(struct bt_context *bt_ctx) begin_pos.type = BT_SEEK_BEGIN; iter = bt_ctf_iter_create(bt_ctx, &begin_pos, NULL); - bt_ctf_iter_add_callback(iter, 0, NULL, 0, - print_timestamp, - NULL, NULL, NULL); - -#if 0 - /* at each event check if we need to refresh */ - bt_ctf_iter_add_callback(iter, 0, NULL, 0, - check_timestamp, - NULL, NULL, NULL); - /* at each event, verify the status of the process table */ - bt_ctf_iter_add_callback(iter, 0, NULL, 0, - fix_process_table, - NULL, NULL, NULL); - /* to handle the scheduling events */ - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sched_switch"), - NULL, 0, handle_sched_switch, NULL, NULL, NULL); - /* to clean up the process table */ - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sched_process_free"), - NULL, 0, handle_sched_process_free, NULL, NULL, NULL); - /* to get all the process from the statedumps */ - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string( - "lttng_statedump_process_state"), - NULL, 0, handle_statedump_process_state, - NULL, NULL, NULL); - - /* for IO top */ - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("exit_syscall"), - NULL, 0, handle_exit_syscall, NULL, NULL, NULL); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sys_write"), - NULL, 0, handle_sys_write, NULL, NULL, NULL); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sys_read"), - NULL, 0, handle_sys_read, NULL, NULL, NULL); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sys_open"), - NULL, 0, handle_sys_open, NULL, NULL, NULL); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string("sys_close"), - NULL, 0, handle_sys_close, NULL, NULL, NULL); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string( + if (opt_textdump) { + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + print_timestamp, + NULL, NULL, NULL); + } else { + /* at each event check if we need to refresh */ + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + check_timestamp, + NULL, NULL, NULL); + /* at each event, verify the status of the process table */ + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + fix_process_table, + NULL, NULL, NULL); + /* to handle the scheduling events */ + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sched_switch"), + NULL, 0, handle_sched_switch, NULL, NULL, NULL); + /* to clean up the process table */ + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sched_process_free"), + NULL, 0, handle_sched_process_free, NULL, NULL, NULL); + /* to get all the process from the statedumps */ + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string( + "lttng_statedump_process_state"), + NULL, 0, handle_statedump_process_state, + NULL, NULL, NULL); + + /* for IO top */ + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("exit_syscall"), + NULL, 0, handle_exit_syscall, NULL, NULL, NULL); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sys_write"), + NULL, 0, handle_sys_write, NULL, NULL, NULL); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sys_read"), + NULL, 0, handle_sys_read, NULL, NULL, NULL); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sys_open"), + NULL, 0, handle_sys_open, NULL, NULL, NULL); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string("sys_close"), + NULL, 0, handle_sys_close, NULL, NULL, NULL); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string( "lttng_statedump_file_descriptor"), - NULL, 0, handle_statedump_file_descriptor, - NULL, NULL, NULL); -#endif + NULL, 0, handle_statedump_file_descriptor, + NULL, NULL, NULL); + } + while ((event = bt_ctf_iter_read_event(iter)) != NULL) { ret = bt_iter_next(bt_ctf_get_iter(iter)); if (ret < 0) @@ -875,8 +875,8 @@ void *setup_live_tracing() strcpy(chan.name, channel_name); chan.attr.overwrite = 0; - chan.attr.subbuf_size = 32768; -// chan.attr.subbuf_size = 1048576; /* 1MB */ +// chan.attr.subbuf_size = 32768; + chan.attr.subbuf_size = 1048576; /* 1MB */ chan.attr.num_subbuf = 4; chan.attr.switch_timer_interval = 0; chan.attr.read_timer_interval = 200; @@ -891,13 +891,19 @@ void *setup_live_tracing() memset(&ev, '\0', sizeof(struct lttng_event)); //sprintf(ev.name, "sched_switch"); ev.type = LTTNG_EVENT_TRACEPOINT; - if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { fprintf(stderr,"error enabling event : %s\n", helper_lttcomm_get_readable_code(ret)); goto end; } + ev.type = LTTNG_EVENT_SYSCALL; + if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { + fprintf(stderr,"error enabling syscalls : %s\n", + helper_lttcomm_get_readable_code(ret)); + goto end; + } + kctxpid.ctx = LTTNG_EVENT_CONTEXT_PID; lttng_add_context(handle, &kctxpid, NULL, NULL); kctxppid.ctx = LTTNG_EVENT_CONTEXT_PPID; @@ -915,18 +921,9 @@ void *setup_live_tracing() helper_kernctl_buffer_flush(consumerd_metadata); - /* Create thread to manage the polling/writing of traces */ - ret = pthread_create(&thread_live_consume, NULL, live_consume, NULL); - if (ret != 0) { - perror("pthread_create"); - goto end; - } - /* block until metadata is ready */ sem_init(&metadata_available, 0, 0); - //init_lttngtop(); - end: return NULL; } @@ -946,15 +943,18 @@ int main(int argc, char **argv) } if (!opt_input_path) { - pthread_create(&live_trace_thread, NULL, setup_live_tracing, (void *) NULL); + setup_live_tracing(); + init_lttngtop(); + if (!opt_textdump) { + pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL); + pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL); + } + live_consume(); + sleep(2000); - printf("STOPPING\n"); lttng_stop_tracing("test"); - printf("DESTROYING\n"); lttng_destroy_session("test"); - printf("CANCELLING\n"); - pthread_cancel(live_trace_thread); goto end; } else { init_lttngtop(); -- 2.34.1 From 30b646c4e7aab1e1bee8fef60619a61bd80bedad Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 15 Aug 2012 22:03:24 -0400 Subject: [PATCH 07/16] hash table for processes and fix path for traces Signed-off-by: Julien Desfossez --- src/common.c | 26 +++++++++++++++++--------- src/lttngtop.c | 7 +++++-- src/lttngtoptypes.h | 1 + 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index bff5b00..43e258b 100644 --- a/src/common.c +++ b/src/common.c @@ -103,20 +103,15 @@ char *get_context_comm(const struct bt_ctf_event *event) /* * To get the parent process, put the pid in the tid field * because the parent process gets pid = tid - * - * FIXME : char *comm useful ??? */ struct processtop *find_process_tid(struct lttngtop *ctx, int tid, char *comm) { - gint i; struct processtop *tmp; - for (i = 0; i < ctx->process_table->len; i++) { - tmp = g_ptr_array_index(ctx->process_table, i); - if (tmp && tmp->tid == tid) - return tmp; - } - return NULL; + tmp = g_hash_table_lookup(ctx->process_hash_table, + (gconstpointer) (unsigned long) tid); + + return tmp; } struct processtop* add_proc(struct lttngtop *ctx, int tid, char *comm, @@ -142,6 +137,8 @@ struct processtop* add_proc(struct lttngtop *ctx, int tid, char *comm, newproc->threads = g_ptr_array_new(); newproc->perf = g_hash_table_new(g_str_hash, g_str_equal); g_ptr_array_add(ctx->process_table, newproc); + g_hash_table_insert(ctx->process_hash_table, + (gpointer) (unsigned long) tid, newproc); ctx->nbnewthreads++; ctx->nbthreads++; @@ -175,6 +172,9 @@ void death_proc(struct lttngtop *ctx, int tid, char *comm, { struct processtop *tmp; tmp = find_process_tid(ctx, tid, comm); + + g_hash_table_remove(ctx->process_hash_table, + (gpointer) (unsigned long) tid); if (tmp && strcmp(tmp->comm, comm) == 0) { tmp->death = timestamp; ctx->nbdeadthreads++; @@ -283,6 +283,11 @@ void copy_perf_counter(gpointer key, gpointer value, gpointer new_table) g_hash_table_insert((GHashTable *) new_table, strdup(key), newperf); } +void copy_process_table(gpointer key, gpointer value, gpointer new_table) +{ + g_hash_table_insert((GHashTable *) new_table, key, value); +} + void rotate_perfcounter() { int i; struct processtop *tmp; @@ -360,6 +365,9 @@ struct lttngtop* get_copy_lttngtop(unsigned long start, unsigned long end) dst->process_table = g_ptr_array_new(); dst->files_table = g_ptr_array_new(); dst->cpu_table = g_ptr_array_new(); + dst->process_hash_table = g_hash_table_new(g_direct_hash, g_direct_equal); + g_hash_table_foreach(lttngtop.process_hash_table, copy_process_table, + dst->process_hash_table); rotate_cputime(end); diff --git a/src/lttngtop.c b/src/lttngtop.c index 7c0ec53..9ac8d39 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -343,6 +343,7 @@ void init_lttngtop() copies = g_ptr_array_new(); global_perf_liszt = g_hash_table_new(g_str_hash, g_str_equal); + sem_init(&goodtodisplay, 0, 0); sem_init(&goodtoupdate, 0, 1); sem_init(&timer, 0, 1); @@ -355,6 +356,8 @@ void init_lttngtop() lttngtop.nbthreads = 0; lttngtop.nbfiles = 0; + lttngtop.process_hash_table = g_hash_table_new(g_direct_hash, + g_direct_equal); lttngtop.process_table = g_ptr_array_new(); lttngtop.files_table = g_ptr_array_new(); lttngtop.cpu_table = g_ptr_array_new(); @@ -770,12 +773,12 @@ void *live_consume() if (!metadata_ready) { sem_wait(&metadata_available); - if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { + if (access("/tmp/livesession/metadata", F_OK) != 0) { fprintf(stderr,"no metadata\n"); return NULL; } metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); + metadata_fp = fopen("/tmp/livesession/metadata", "r"); } if (!trace_opened) { diff --git a/src/lttngtoptypes.h b/src/lttngtoptypes.h index c69ea01..e01f804 100644 --- a/src/lttngtoptypes.h +++ b/src/lttngtoptypes.h @@ -21,6 +21,7 @@ #include struct lttngtop { + GHashTable *process_hash_table; /* struct processtop */ GPtrArray *process_table; /* struct processtop */ GPtrArray *files_table; /* struct files */ GPtrArray *cpu_table; /* struct cputime */ -- 2.34.1 From eb677852b5682dc127eb431b2cabf978fdc5011a Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Thu, 16 Aug 2012 23:35:00 -0400 Subject: [PATCH 08/16] fully working Signed-off-by: Julien Desfossez --- src/lttngtop.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index 9ac8d39..892cfd0 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -138,7 +138,6 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat struct tm start; uint64_t ts_nsec_start; - timestamp = bt_ctf_get_timestamp(call_data); start = format_timestamp(timestamp); @@ -343,7 +342,6 @@ void init_lttngtop() copies = g_ptr_array_new(); global_perf_liszt = g_hash_table_new(g_str_hash, g_str_equal); - sem_init(&goodtodisplay, 0, 0); sem_init(&goodtoupdate, 0, 1); sem_init(&timer, 0, 1); @@ -766,34 +764,33 @@ end: return ret; } -void *live_consume() +void live_consume(struct bt_context **bt_ctx) { - struct bt_context *bt_ctx = NULL; int ret; if (!metadata_ready) { sem_wait(&metadata_available); - if (access("/tmp/livesession/metadata", F_OK) != 0) { + if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { fprintf(stderr,"no metadata\n"); - return NULL; + goto end; } metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/metadata", "r"); + metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); } if (!trace_opened) { - bt_ctx = bt_context_create(); - ret = bt_context_add_trace(bt_ctx, NULL, "ctf", + *bt_ctx = bt_context_create(); + ret = bt_context_add_trace(*bt_ctx, NULL, "ctf", lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); if (ret < 0) { printf("Error adding trace\n"); - return NULL; + goto end; } trace_opened = 1; } - iter_trace(bt_ctx); - return NULL; +end: + return; } int setup_consumer(char *command_sock_path, pthread_t *threads, @@ -856,7 +853,7 @@ void *setup_live_tracing() /* setup the session */ dom.type = LTTNG_DOMAIN_KERNEL; - ret = system("rm -rf /tmp/livesession"); + ret = unlink("/tmp/livesession"); lttng_destroy_session("test"); if ((ret = lttng_create_session("test", "/tmp/livesession")) < 0) { @@ -952,9 +949,13 @@ int main(int argc, char **argv) pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL); pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL); } - live_consume(); + live_consume(&bt_ctx); + iter_trace(bt_ctx); + + quit = 1; + pthread_join(display_thread, NULL); + pthread_join(timer_thread, NULL); - sleep(2000); lttng_stop_tracing("test"); lttng_destroy_session("test"); -- 2.34.1 From cade341846ca2769283fb568700b1bd2732f28d0 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Thu, 16 Aug 2012 23:46:09 -0400 Subject: [PATCH 09/16] flush at every second Signed-off-by: Julien Desfossez --- src/lttngtop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lttngtop.c b/src/lttngtop.c index 892cfd0..7d89e5c 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -88,9 +88,13 @@ static struct poptOption long_options[] = { void *refresh_thread(void *p) { + struct mmap_stream *mmap_info; + while (1) { if (quit) return NULL; + bt_list_for_each_entry(mmap_info, &mmap_list.head, list) + helper_kernctl_buffer_flush(mmap_info->fd); sem_wait(&pause_sem); sem_post(&pause_sem); sem_post(&timer); -- 2.34.1 From ae9e85c7301dea169bc50c91d927eccd2c944e92 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 17 Aug 2012 12:30:05 -0400 Subject: [PATCH 10/16] exit cleanly Signed-off-by: Julien Desfossez --- src/common.h | 2 ++ src/cursesdisplay.c | 8 ++++++-- src/lttngtop.c | 30 +++++++++++++++++++----------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/common.h b/src/common.h index 3738331..1bde45c 100644 --- a/src/common.h +++ b/src/common.h @@ -31,6 +31,8 @@ sem_t goodtodisplay, goodtoupdate, timer, pause_sem, end_trace_sem, bootstrap; GPtrArray *copies; /* struct lttngtop */ GHashTable *global_perf_liszt; +extern int quit; + struct lttngtop *data; struct processtop *find_process_tid(struct lttngtop *ctx, int pid, char *comm); diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index 25fe1f9..c8ac5db 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -74,11 +74,13 @@ void reset_ncurses() { curs_set(1); endwin(); - exit(0); + quit = 1; } static void handle_sigterm(int signal) { + fprintf(stderr, "caugh signal\n"); + pthread_cancel(keyboard_thread); reset_ncurses(); } @@ -119,6 +121,7 @@ void init_screen() define_key("\033[17;2~", KEY_F(18)); } signal(SIGTERM, handle_sigterm); + signal(SIGINT, handle_sigterm); mousemask(BUTTON1_CLICKED, NULL); refresh(); } @@ -1491,6 +1494,8 @@ void *handle_keyboard(void *p) case KEY_F(10): case 'q': reset_ncurses(); + /* exit keyboard thread */ + pthread_exit(0); break; case 't': toggle_threads *= -1; @@ -1502,7 +1507,6 @@ void *handle_keyboard(void *p) } else { resume_display(); } - break; case 'r': toggle_pref_panel(); break; diff --git a/src/lttngtop.c b/src/lttngtop.c index 7d89e5c..8a3416c 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -53,13 +53,14 @@ const char *opt_input_path; int opt_textdump; +int quit = 0; + struct lttngtop *copy; pthread_t display_thread; pthread_t timer_thread; unsigned long refresh_display = 1 * NSEC_PER_SEC; unsigned long last_display_update = 0; -int quit = 0; /* list of FDs available for being read with snapshots */ struct mmap_stream_list mmap_list; @@ -91,8 +92,12 @@ void *refresh_thread(void *p) struct mmap_stream *mmap_info; while (1) { - if (quit) - return NULL; + if (quit) { + sem_post(&pause_sem); + sem_post(&timer); + sem_post(&goodtodisplay); + pthread_exit(0); + } bt_list_for_each_entry(mmap_info, &mmap_list.head, list) helper_kernctl_buffer_flush(mmap_info->fd); sem_wait(&pause_sem); @@ -118,17 +123,18 @@ void *ncurses_display(void *p) sem_wait(&goodtodisplay); sem_wait(&pause_sem); + if (quit) { + reset_ncurses(); + pthread_exit(0); + } + + copy = g_ptr_array_index(copies, current_display_index); assert(copy); display(current_display_index++); sem_post(&goodtoupdate); sem_post(&pause_sem); - - if (quit) { - reset_ncurses(); - pthread_exit(0); - } } } @@ -468,7 +474,9 @@ void iter_trace(struct bt_context *bt_ctx) NULL, NULL, NULL); } - while ((event = bt_ctf_iter_read_event(iter)) != NULL) { + while (((event = bt_ctf_iter_read_event(iter)) != NULL)) { + if (quit) + goto end_iter; ret = bt_iter_next(bt_ctf_get_iter(iter)); if (ret < 0) goto end_iter; @@ -956,9 +964,9 @@ int main(int argc, char **argv) live_consume(&bt_ctx); iter_trace(bt_ctx); + pthread_join(timer_thread, NULL); quit = 1; pthread_join(display_thread, NULL); - pthread_join(timer_thread, NULL); lttng_stop_tracing("test"); lttng_destroy_session("test"); @@ -984,8 +992,8 @@ int main(int argc, char **argv) iter_trace(bt_ctx); - quit = 1; pthread_join(display_thread, NULL); + quit = 1; pthread_join(timer_thread, NULL); } -- 2.34.1 From 33572a17ebf19098e1f1d3f1088e000e276eec60 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 17 Aug 2012 13:22:16 -0400 Subject: [PATCH 11/16] cleanup exit path Signed-off-by: Julien Desfossez --- src/cursesdisplay.c | 5 ++++- src/lttngtop.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index c8ac5db..02764dd 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -75,11 +75,13 @@ void reset_ncurses() curs_set(1); endwin(); quit = 1; + sem_post(&pause_sem); + sem_post(&timer); + sem_post(&goodtodisplay); } static void handle_sigterm(int signal) { - fprintf(stderr, "caugh signal\n"); pthread_cancel(keyboard_thread); reset_ncurses(); } @@ -1507,6 +1509,7 @@ void *handle_keyboard(void *p) } else { resume_display(); } + break; case 'r': toggle_pref_panel(); break; diff --git a/src/lttngtop.c b/src/lttngtop.c index 8a3416c..26faf1d 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -124,11 +124,12 @@ void *ncurses_display(void *p) sem_wait(&pause_sem); if (quit) { + sem_post(&pause_sem); + sem_post(&timer); reset_ncurses(); pthread_exit(0); } - copy = g_ptr_array_index(copies, current_display_index); assert(copy); display(current_display_index++); -- 2.34.1 From 050f9cf91c01ff380df000bd0daa559285b7e787 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Mon, 20 Aug 2012 10:33:22 -0400 Subject: [PATCH 12/16] fix race on startup and support for cpu hotplug Signed-off-by: Julien Desfossez --- src/cputop.c | 3 +- src/lttngtop.c | 80 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/cputop.c b/src/cputop.c index a0ff279..2e0ccdd 100644 --- a/src/cputop.c +++ b/src/cputop.c @@ -33,7 +33,8 @@ void update_cputop_data(unsigned long timestamp, int64_t cpu, int prev_pid, elapsed = timestamp - tmpcpu->task_start; tmpcpu->current_task->totalcpunsec += elapsed; tmpcpu->current_task->threadstotalcpunsec += elapsed; - if (tmpcpu->current_task->pid != tmpcpu->current_task->tid) + if (tmpcpu->current_task->threadparent && + tmpcpu->current_task->pid != tmpcpu->current_task->tid) tmpcpu->current_task->threadparent->threadstotalcpunsec += elapsed; } diff --git a/src/lttngtop.c b/src/lttngtop.c index 26faf1d..9b650f4 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -70,9 +70,7 @@ struct lttng_consumer_local_data *ctx = NULL; /* list of snapshots currently not consumed */ GPtrArray *available_snapshots; sem_t metadata_available; -FILE *metadata_fp; -int trace_opened = 0; -int metadata_ready = 0; +int reload_trace = 0; enum { OPT_NONE = 0, @@ -475,8 +473,8 @@ void iter_trace(struct bt_context *bt_ctx) NULL, NULL, NULL); } - while (((event = bt_ctf_iter_read_event(iter)) != NULL)) { - if (quit) + while ((event = bt_ctf_iter_read_event(iter)) != NULL) { + if (quit || reload_trace) goto end_iter; ret = bt_iter_next(bt_ctf_get_iter(iter)); if (ret < 0) @@ -773,6 +771,8 @@ int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd) ret = 0; } + reload_trace = 1; + end: return ret; } @@ -780,26 +780,21 @@ end: void live_consume(struct bt_context **bt_ctx) { int ret; + FILE *metadata_fp; - if (!metadata_ready) { - sem_wait(&metadata_available); - if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { - fprintf(stderr,"no metadata\n"); - goto end; - } - metadata_ready = 1; - metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); + sem_wait(&metadata_available); + if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) { + fprintf(stderr,"no metadata\n"); + goto end; } + metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r"); - if (!trace_opened) { - *bt_ctx = bt_context_create(); - ret = bt_context_add_trace(*bt_ctx, NULL, "ctf", - lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); - if (ret < 0) { - printf("Error adding trace\n"); - goto end; - } - trace_opened = 1; + *bt_ctx = bt_context_create(); + ret = bt_context_add_trace(*bt_ctx, NULL, "ctf", + lttngtop_ctf_packet_seek, &mmap_list, metadata_fp); + if (ret < 0) { + printf("Error adding trace\n"); + goto end; } end: @@ -880,6 +875,16 @@ void *setup_live_tracing() goto end; } + /* + * FIXME : need to let the + * helper_lttng_consumer_thread_receive_fds create the + * socket. + * Cleaner solution ? + */ + while (access(command_sock_path, F_OK)) { + sleep(0.1); + } + if ((ret = lttng_register_consumer(handle, command_sock_path)) < 0) { fprintf(stderr,"error registering consumer : %s\n", helper_lttcomm_get_readable_code(ret)); @@ -945,6 +950,8 @@ int main(int argc, char **argv) { int ret; struct bt_context *bt_ctx = NULL; + struct mmap_stream *mmap_info; + unsigned long mmap_len; ret = parse_options(argc, argv); if (ret < 0) { @@ -962,8 +969,33 @@ int main(int argc, char **argv) pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL); pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL); } - live_consume(&bt_ctx); - iter_trace(bt_ctx); + while (!quit) { + reload_trace = 0; + live_consume(&bt_ctx); + iter_trace(bt_ctx); + ret = bt_context_remove_trace(bt_ctx, 0); + if (ret != 0) + fprintf(stderr, "error removing trace\n"); + if (bt_ctx) { + bt_context_put(bt_ctx); + } + + /* + * since we receive all FDs every time there is an + * update and the FD number is different every time, + * we don't know which one are valid. + * so we check if all FDs are usable with a simple + * ioctl call. + */ + bt_list_for_each_entry(mmap_info, &mmap_list.head, list) { + ret = helper_kernctl_get_mmap_len(mmap_info->fd, &mmap_len); + if (ret != 0) { + ret = errno; + bt_list_del(&mmap_info->list); + } + } + sem_post(&metadata_available); + } pthread_join(timer_thread, NULL); quit = 1; -- 2.34.1 From 1a70b8acdfee3652b0295827825919d710c26486 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 21 Aug 2012 12:54:57 -0400 Subject: [PATCH 13/16] error handling on setup live tracing Signed-off-by: Julien Desfossez --- src/lttngtop.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lttngtop.c b/src/lttngtop.c index 9b650f4..c567878 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -834,7 +834,7 @@ end: return ret; } -void *setup_live_tracing() +int setup_live_tracing() { struct lttng_domain dom; struct lttng_channel chan; @@ -853,7 +853,7 @@ void *setup_live_tracing() if ((ret = setup_consumer(command_sock_path, threads, ctx)) < 0) { fprintf(stderr,"error setting up consumer\n"); - goto end; + goto error; } available_snapshots = g_ptr_array_new(); @@ -867,12 +867,12 @@ void *setup_live_tracing() if ((ret = lttng_create_session("test", "/tmp/livesession")) < 0) { fprintf(stderr,"error creating the session : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error; } if ((handle = lttng_create_handle("test", &dom)) == NULL) { fprintf(stderr,"error creating handle\n"); - goto end; + goto error_session; } /* @@ -888,7 +888,7 @@ void *setup_live_tracing() if ((ret = lttng_register_consumer(handle, command_sock_path)) < 0) { fprintf(stderr,"error registering consumer : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error_session; } strcpy(chan.name, channel_name); @@ -903,7 +903,7 @@ void *setup_live_tracing() if ((ret = lttng_enable_channel(handle, &chan)) < 0) { fprintf(stderr,"error creating channel : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error_session; } memset(&ev, '\0', sizeof(struct lttng_event)); @@ -912,14 +912,14 @@ void *setup_live_tracing() if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { fprintf(stderr,"error enabling event : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error_session; } ev.type = LTTNG_EVENT_SYSCALL; if ((ret = lttng_enable_event(handle, &ev, channel_name)) < 0) { fprintf(stderr,"error enabling syscalls : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error_session; } kctxpid.ctx = LTTNG_EVENT_CONTEXT_PID; @@ -934,7 +934,7 @@ void *setup_live_tracing() if ((ret = lttng_start_tracing("test")) < 0) { fprintf(stderr,"error starting tracing : %s\n", helper_lttcomm_get_readable_code(ret)); - goto end; + goto error_session; } helper_kernctl_buffer_flush(consumerd_metadata); @@ -942,8 +942,12 @@ void *setup_live_tracing() /* block until metadata is ready */ sem_init(&metadata_available, 0, 0); -end: - return NULL; + return 0; + +error_session: + lttng_destroy_session("test"); +error: + return -1; } int main(int argc, char **argv) @@ -963,7 +967,10 @@ int main(int argc, char **argv) } if (!opt_input_path) { - setup_live_tracing(); + ret = setup_live_tracing(); + if (ret < 0) { + goto end; + } init_lttngtop(); if (!opt_textdump) { pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL); @@ -990,7 +997,6 @@ int main(int argc, char **argv) bt_list_for_each_entry(mmap_info, &mmap_list.head, list) { ret = helper_kernctl_get_mmap_len(mmap_info->fd, &mmap_len); if (ret != 0) { - ret = errno; bt_list_del(&mmap_info->list); } } -- 2.34.1 From 1402044a1577c9b62b60f64fdb48ae9524be458c Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 21 Aug 2012 13:57:43 -0400 Subject: [PATCH 14/16] Basic support to display vPID and vTID Signed-off-by: Julien Desfossez --- src/common.c | 50 ++++++++++++++++++++++++++++++++++++++++++- src/common.h | 5 ++++- src/cursesdisplay.c | 52 +++++++++++++++++++++++++++++++++++++++------ src/lttngtop.c | 20 +++++++++++++++-- src/lttngtoptypes.h | 7 +++--- 5 files changed, 119 insertions(+), 15 deletions(-) diff --git a/src/common.c b/src/common.c index 43e258b..fd941bd 100644 --- a/src/common.c +++ b/src/common.c @@ -84,6 +84,51 @@ uint64_t get_context_ppid(const struct bt_ctf_event *event) return ppid; } +uint64_t get_context_vtid(const struct bt_ctf_event *event) +{ + const struct definition *scope; + uint64_t vtid; + + scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT); + vtid = bt_ctf_get_int64(bt_ctf_get_field(event, + scope, "_vtid")); + if (bt_ctf_field_get_error()) { + return -1ULL; + } + + return vtid; +} + +uint64_t get_context_vpid(const struct bt_ctf_event *event) +{ + const struct definition *scope; + uint64_t vpid; + + scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT); + vpid = bt_ctf_get_int64(bt_ctf_get_field(event, + scope, "_vpid")); + if (bt_ctf_field_get_error()) { + return -1ULL; + } + + return vpid; +} + +uint64_t get_context_vppid(const struct bt_ctf_event *event) +{ + const struct definition *scope; + uint64_t vppid; + + scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT); + vppid = bt_ctf_get_int64(bt_ctf_get_field(event, + scope, "_vppid")); + if (bt_ctf_field_get_error()) { + return -1ULL; + } + + return vppid; +} + char *get_context_comm(const struct bt_ctf_event *event) { const struct bt_definition *scope; @@ -149,12 +194,15 @@ struct processtop* add_proc(struct lttngtop *ctx, int tid, char *comm, } struct processtop* update_proc(struct processtop* proc, int pid, int tid, - int ppid, char *comm) + int ppid, int vpid, int vtid, int vppid, char *comm) { if (proc) { proc->pid = pid; proc->tid = tid; proc->ppid = ppid; + proc->vpid = vpid; + proc->vtid = vtid; + proc->vppid = vppid; if (strcmp(proc->comm, comm) != 0) { free(proc->comm); proc->comm = strdup(comm); diff --git a/src/common.h b/src/common.h index 1bde45c..2458c85 100644 --- a/src/common.h +++ b/src/common.h @@ -39,7 +39,7 @@ struct processtop *find_process_tid(struct lttngtop *ctx, int pid, char *comm); struct processtop* add_proc(struct lttngtop *ctx, int pid, char *comm, unsigned long timestamp); struct processtop* update_proc(struct processtop* proc, int pid, int tid, - int ppid, char *comm); + int ppid, int vpid, int vtid, int vppid, char *comm); void add_thread(struct processtop *parent, struct processtop *thread); struct processtop* get_proc(struct lttngtop *ctx, int tid, char *comm, unsigned long timestamp); @@ -64,6 +64,9 @@ uint64_t get_context_tid(const struct bt_ctf_event *event); uint64_t get_context_pid(const struct bt_ctf_event *event); uint64_t get_context_ppid(const struct bt_ctf_event *event); char *get_context_comm(const struct bt_ctf_event *event); +uint64_t get_context_vtid(const struct bt_ctf_event *event); +uint64_t get_context_vpid(const struct bt_ctf_event *event); +uint64_t get_context_vppid(const struct bt_ctf_event *event); enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, void *private_data); diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index 02764dd..62c4ba4 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -59,6 +59,7 @@ char log_lines[MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES]; int max_elements = 80; int toggle_threads = 1; +int toggle_virt = -1; int toggle_pause = -1; int max_center_lines; @@ -66,7 +67,7 @@ GPtrArray *selected_processes; pthread_t keyboard_thread; -struct header_view cputopview[4]; +struct header_view cputopview[6]; struct header_view iostreamtopview[3]; struct header_view fileview[3]; @@ -78,6 +79,8 @@ void reset_ncurses() sem_post(&pause_sem); sem_post(&timer); sem_post(&goodtodisplay); + sem_post(&end_trace_sem); + sem_post(&goodtoupdate); } static void handle_sigterm(int signal) @@ -288,6 +291,7 @@ void update_footer() print_key(footer, "q", "Quit ", 0); print_key(footer, "r", "Pref ", 0); print_key(footer, "t", "Threads ", toggle_threads); + print_key(footer, "v", "Virt ", toggle_virt); print_key(footer, "p", "Pause ", toggle_pause); wrefresh(footer); @@ -525,6 +529,7 @@ void update_cputop_display() double maxcputime; int nblinedisplayed = 0; int current_line = 0; + int current_row_offset; int column; elapsed = data->end - data->start; @@ -544,7 +549,10 @@ void update_cputop_display() set_window_title(center, "CPU Top"); wattron(center, A_BOLD); column = 1; - for (i = 0; i < 4; i++) { + for (i = 0; i < 6; i++) { + if (toggle_virt < 0 && (i == 3 || i == 4)) { + continue; + } if (cputopview[i].sort) { wattron(center, A_UNDERLINE); pref_current_sort = i; @@ -561,6 +569,7 @@ void update_cputop_display() for (i = list_offset; i < data->process_table->len && nblinedisplayed < max_center_lines; i++) { tmp = g_ptr_array_index(data->process_table, i); + current_row_offset = 1; if (tmp->pid != tmp->tid) if (toggle_threads == -1) continue; @@ -575,14 +584,31 @@ void update_cputop_display() mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); } /* CPU(%) */ - mvwprintw(center, current_line + header_offset, 1, "%1.2f", + mvwprintw(center, current_line + header_offset, + current_row_offset, "%1.2f", tmp->totalcpunsec / maxcputime); + current_row_offset += 10; /* PID */ - mvwprintw(center, current_line + header_offset, 11, "%d", tmp->pid); + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->pid); + current_row_offset += 10; /* TID */ - mvwprintw(center, current_line + header_offset, 21, "%d", tmp->tid); + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->tid); + current_row_offset += 10; + if (toggle_virt > 0) { + /* VPID */ + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->vpid); + current_row_offset += 10; + /* VTID */ + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->vtid); + current_row_offset += 10; + } /* NAME */ - mvwprintw(center, current_line + header_offset, 31, "%s", tmp->comm); + mvwprintw(center, current_line + header_offset, + current_row_offset, "%s", tmp->comm); wattroff(center, COLOR_PAIR(6)); wattroff(center, COLOR_PAIR(5)); nblinedisplayed++; @@ -672,6 +698,12 @@ void update_process_details() wprintw(center, "%d", tmp->pid); print_key_title("PPID", line++); wprintw(center, "%d", tmp->ppid); + print_key_title("VPID", line++); + wprintw(center, "%d", tmp->vpid); + print_key_title("VTID", line++); + wprintw(center, "%d", tmp->vtid); + print_key_title("VPPID", line++); + wprintw(center, "%d", tmp->vppid); print_key_title("CPU", line++); wprintw(center, "%1.2f %%", tmp->totalcpunsec/maxcputime); @@ -1513,6 +1545,10 @@ void *handle_keyboard(void *p) case 'r': toggle_pref_panel(); break; + case 'v': + toggle_virt *= -1; + update_current_view(); + break; /* ESCAPE, but slow to process, don't know why */ case 27: if (pref_panel_visible) @@ -1539,7 +1575,9 @@ void init_view_headers() cputopview[0].sort = 1; cputopview[1].title = strdup("PID"); cputopview[2].title = strdup("TID"); - cputopview[3].title = strdup("NAME"); + cputopview[3].title = strdup("VPID"); + cputopview[4].title = strdup("VTID"); + cputopview[5].title = strdup("NAME"); iostreamtopview[0].title = strdup("R (B/sec)"); iostreamtopview[1].title = strdup("W (B/sec)"); diff --git a/src/lttngtop.c b/src/lttngtop.c index c567878..d282011 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -93,11 +93,15 @@ void *refresh_thread(void *p) if (quit) { sem_post(&pause_sem); sem_post(&timer); + sem_post(&end_trace_sem); sem_post(&goodtodisplay); + sem_post(&goodtoupdate); pthread_exit(0); } + if (!opt_input_path) { bt_list_for_each_entry(mmap_info, &mmap_list.head, list) helper_kernctl_buffer_flush(mmap_info->fd); + } sem_wait(&pause_sem); sem_post(&pause_sem); sem_post(&timer); @@ -293,7 +297,7 @@ void update_perf_counter(struct processtop *proc, const struct bt_ctf_event *eve enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, void *private_data) { - int pid, tid, ppid; + int pid, tid, ppid, vpid, vtid, vppid; char *comm; struct processtop *parent, *child; unsigned long timestamp; @@ -314,6 +318,18 @@ enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, if (ppid == -1ULL) { goto error; } + vpid = get_context_vpid(call_data); + if (pid == -1ULL) { + vpid = -1; + } + vtid = get_context_vtid(call_data); + if (tid == -1ULL) { + vtid = -1; + } + vppid = get_context_vppid(call_data); + if (ppid == -1ULL) { + vppid = -1; + } comm = get_context_comm(call_data); if (!comm) { goto error; @@ -323,7 +339,7 @@ enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, child = find_process_tid(<tngtop, tid, comm); if (!child) child = add_proc(<tngtop, tid, comm, timestamp); - update_proc(child, pid, tid, ppid, comm); + update_proc(child, pid, tid, ppid, vpid, vtid, vppid, comm); if (pid != tid) { /* find or create the parent */ diff --git a/src/lttngtoptypes.h b/src/lttngtoptypes.h index e01f804..66b2079 100644 --- a/src/lttngtoptypes.h +++ b/src/lttngtoptypes.h @@ -44,12 +44,11 @@ struct processtop { char *comm; int tid; int ppid; - int oldpid; - int oldtid; - int oldppid; + int vpid; + int vtid; + int vppid; unsigned long birth; unsigned long death; - unsigned long lastactivity; /* Files managing */ GPtrArray *process_files_table; struct file_history *files_history; -- 2.34.1 From dc3eb0c3f241c6b372ee2c15d53bf4cb47d0c9aa Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 21 Aug 2012 14:05:46 -0400 Subject: [PATCH 15/16] live VPID and VTID Signed-off-by: Julien Desfossez --- src/lttngtop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lttngtop.c b/src/lttngtop.c index d282011..571b0f8 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -946,6 +946,10 @@ int setup_live_tracing() lttng_add_context(handle, &kctxcomm, NULL, NULL); kctxtid.ctx = LTTNG_EVENT_CONTEXT_TID; lttng_add_context(handle, &kctxtid, NULL, NULL); + kctxpid.ctx = LTTNG_EVENT_CONTEXT_VPID; + lttng_add_context(handle, &kctxpid, NULL, NULL); + kctxtid.ctx = LTTNG_EVENT_CONTEXT_VTID; + lttng_add_context(handle, &kctxtid, NULL, NULL); if ((ret = lttng_start_tracing("test")) < 0) { fprintf(stderr,"error starting tracing : %s\n", -- 2.34.1 From 11d218ce379a7c08bec00b808c7bcfe5943a7208 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 22 Aug 2012 20:48:51 -0400 Subject: [PATCH 16/16] statedump vpid, vtid, vppid Signed-off-by: Julien Desfossez --- src/common.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index fd941bd..eca4d49 100644 --- a/src/common.c +++ b/src/common.c @@ -523,7 +523,7 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, const struct bt_definition *scope; struct processtop *proc; unsigned long timestamp; - int64_t pid, tid; + int64_t pid, tid, ppid, vtid, vpid, vppid; char *procname; timestamp = bt_ctf_get_timestamp(call_data); @@ -538,9 +538,13 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, fprintf(stderr, "Missing pid context info\n"); goto error; } + ppid = bt_ctf_get_int64(bt_ctf_get_field(call_data, + scope, "_ppid")); + if (bt_ctf_field_get_error()) { + fprintf(stderr, "Missing pid context info\n"); + goto error; + } - scope = bt_ctf_get_top_level_scope(call_data, - BT_EVENT_FIELDS); tid = bt_ctf_get_int64(bt_ctf_get_field(call_data, scope, "_tid")); if (bt_ctf_field_get_error()) { @@ -548,6 +552,25 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, goto error; } + vtid = bt_ctf_get_int64(bt_ctf_get_field(call_data, + scope, "_vtid")); + if (bt_ctf_field_get_error()) { + fprintf(stderr, "Missing vtid context info\n"); + goto error; + } + vpid = bt_ctf_get_int64(bt_ctf_get_field(call_data, + scope, "_vpid")); + if (bt_ctf_field_get_error()) { + fprintf(stderr, "Missing vtid context info\n"); + goto error; + } + vppid = bt_ctf_get_int64(bt_ctf_get_field(call_data, + scope, "_vppid")); + if (bt_ctf_field_get_error()) { + fprintf(stderr, "Missing vtid context info\n"); + goto error; + } + /* * FIXME * I first tried with bt_ctf_get_string but doesn`t work at all @@ -567,6 +590,7 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, proc = find_process_tid(<tngtop, tid, procname); if (proc == NULL) proc = add_proc(<tngtop, tid, procname, timestamp); + update_proc(proc, pid, tid, ppid, vpid, vtid, vppid, procname); free(proc->comm); proc->comm = strdup(procname); -- 2.34.1