X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttngtop.c;h=ba778821f78352b1ae809f71cb741d71d42f9bfd;hb=796712db4b65553e3f31213c2c2c2c9ad7a686b6;hp=dd3130d975adac8dc736f4a3858606af29ac850f;hpb=54761a45d53fe4b891dd60f17cbec0d3f85ab28d;p=lttngtop.git diff --git a/src/lttngtop.c b/src/lttngtop.c index dd3130d..ba77882 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -63,6 +63,7 @@ const char *opt_input_path; int opt_textdump; int opt_child; int opt_begin; +int opt_all; int quit = 0; @@ -73,6 +74,7 @@ pthread_t timer_thread; unsigned long refresh_display = 1 * NSEC_PER_SEC; unsigned long last_display_update = 0; unsigned long last_event_ts = 0; +struct syscall *last_syscall; /* list of FDs available for being read with snapshots */ struct bt_mmap_stream_list mmap_list; @@ -96,6 +98,7 @@ enum { OPT_RELAY_HOSTNAME, OPT_KPROBES, OPT_BEGIN, + OPT_ALL, }; static struct poptOption long_options[] = { @@ -109,6 +112,7 @@ static struct poptOption long_options[] = { { "relay-hostname", 'r', POPT_ARG_STRING, &opt_relay_hostname, OPT_RELAY_HOSTNAME, NULL, NULL }, { "kprobes", 'k', POPT_ARG_STRING, &opt_kprobes, OPT_KPROBES, NULL, NULL }, + { "all", 'a', POPT_ARG_NONE, NULL, OPT_ALL, NULL, NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL }, }; @@ -212,13 +216,13 @@ void print_fields(struct bt_ctf_event *event) * 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) +enum bt_cb_ret textdump(struct bt_ctf_event *call_data, void *private_data) { unsigned long timestamp; uint64_t delta; struct tm start; uint64_t ts_nsec_start; - int pid, cpu_id, tid, ret; + int pid, cpu_id, tid, ret, lookup, current_syscall = 0; const struct bt_definition *scope; const char *hostname, *procname; struct cputime *cpu; @@ -243,8 +247,12 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat tid = get_context_tid(call_data); hostname = get_context_hostname(call_data); + if (opt_child) + lookup = pid; + else + lookup = tid; if (opt_tid || opt_hostname || opt_exec_name) { - if (!lookup_filter_tid_list(pid)) { + if (!lookup_filter_tid_list(lookup)) { /* To display when a process of ours in getting scheduled in */ if (strcmp(bt_ctf_event_name(call_data), "sched_switch") == 0) { int next_tid; @@ -258,14 +266,27 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat goto error; } if (!lookup_filter_tid_list(next_tid)) { - goto end; + if (!opt_all) + goto end; + } else { + if (opt_all) + printf("%c[1m", 27); } - } else { + } else if (!opt_all) { goto end; } + } else { + if (opt_all) + printf("%c[1m", 27); } } + if (last_syscall && (strncmp(bt_ctf_event_name(call_data), + "exit_syscall", 12)) != 0) { + last_syscall = NULL; + printf(" ...interrupted...\n"); + } + cpu_id = get_cpu_id(call_data); procname = get_context_comm(call_data); if (strncmp(bt_ctf_event_name(call_data), "sys_", 4) == 0) { @@ -273,15 +294,40 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat cpu->current_syscall = g_new0(struct syscall, 1); cpu->current_syscall->name = strdup(bt_ctf_event_name(call_data)); cpu->current_syscall->ts_start = timestamp; + cpu->current_syscall->cpu_id = cpu_id; + last_syscall = cpu->current_syscall; + current_syscall = 1; } else if ((strncmp(bt_ctf_event_name(call_data), "exit_syscall", 12)) == 0) { struct tm start_ts; + /* Return code of a syscall if it was the last displayed event. */ + if (last_syscall && last_syscall->ts_start == prev_ts) { + if (last_syscall->cpu_id == cpu_id) { + int64_t syscall_ret; + + delta = timestamp - last_syscall->ts_start; + scope = bt_ctf_get_top_level_scope(call_data, + BT_EVENT_FIELDS); + syscall_ret = bt_ctf_get_int64(bt_ctf_get_field(call_data, + scope, "_ret")); + + printf(" = %" PRId64 " (+%" PRIu64 ".%09" PRIu64 ")\n", + syscall_ret, delta / NSEC_PER_SEC, + delta % NSEC_PER_SEC); + last_syscall = NULL; + goto end; + } else { + last_syscall = NULL; + printf(" ...interrupted...\n"); + } + } + cpu = get_cpu(cpu_id); if (cpu->current_syscall) { delta = timestamp - cpu->current_syscall->ts_start; start_ts = format_timestamp(cpu->current_syscall->ts_start); ret = asprintf(&from_syscall, " [from %02d:%02d:%02d.%09" PRIu64 - " (+%" PRIu64 ".%09" PRIu64 ") (cpu %d) %s]\n", + " (+%" PRIu64 ".%09" PRIu64 ") (cpu %d) %s]", start_ts.tm_hour, start_ts.tm_min, start_ts.tm_sec, cpu->current_syscall->ts_start % NSEC_PER_SEC, delta / NSEC_PER_SEC, delta % NSEC_PER_SEC, @@ -292,6 +338,7 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat free(cpu->current_syscall->name); g_free(cpu->current_syscall); cpu->current_syscall = NULL; + last_syscall = NULL; } } @@ -308,9 +355,11 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat (hostname) ? " ": "", cpu_id, procname, pid, tid, bt_ctf_event_name(call_data)); print_fields(call_data); - printf(")%s", (from_syscall) ? from_syscall : "\n"); + printf(")%s%c", (from_syscall) ? from_syscall : "", + (current_syscall) ? '\0' : '\n'); free(from_syscall); + printf("%c[0m", 27); end: return BT_CB_OK; @@ -591,6 +640,7 @@ void usage(FILE *fp) fprintf(fp, " -p, --pid Comma-separated list of PIDs to display\n"); fprintf(fp, " -f, --child Follow threads associated with selected PIDs\n"); fprintf(fp, " -n, --hostname Comma-separated list of hostnames to display (require hostname context in trace)\n"); + fprintf(fp, " -a, --all In textdump mode, display all events but write in bold the processes we are interested in (-f, -p and -n)\n"); fprintf(fp, " -k, --kprobes Comma-separated list of kprobes to insert (same format as lttng enable-event)\n"); fprintf(fp, " -r, --relay-hostname Network live streaming : hostname of the lttng-relayd (default port)\n"); fprintf(fp, " -b, --begin Network live streaming : read the trace for the beginning of the recording\n"); @@ -697,6 +747,9 @@ static int parse_options(int argc, char **argv) case OPT_TEXTDUMP: opt_textdump = 1; break; + case OPT_ALL: + opt_all = 1; + break; case OPT_CHILD: opt_child = 1; break; @@ -796,7 +849,7 @@ void iter_trace(struct bt_context *bt_ctx) NULL, 0, handle_sched_process_free, NULL, NULL, NULL); if (opt_textdump) { bt_ctf_iter_add_callback(iter, 0, NULL, 0, - print_timestamp, + textdump, NULL, NULL, NULL); } else { /* at each event check if we need to refresh */ @@ -1107,6 +1160,7 @@ int main(int argc, char **argv, char **envp) int ret; struct bt_context *bt_ctx = NULL; + //babeltrace_verbose = 1; init_lttngtop(); ret = parse_options(argc, argv); if (ret < 0) {