X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttngtop.c;h=f7af659af385b3032a35dbe59d6ee0427e334360;hb=71ba9228e9371e5732113ad52848e7558f6e52e8;hp=f85d11e1d73653954665458ae0b9b28e6e80c80c;hpb=4251cc67f883927c96fe0d13d14101b8ed01ab43;p=lttngtop.git diff --git a/src/lttngtop.c b/src/lttngtop.c index f85d11e..f7af659 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef LTTNGTOP_MMAP_LIVE #include @@ -217,9 +218,11 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat uint64_t delta; struct tm start; uint64_t ts_nsec_start; - int pid, cpu_id, tid; + int pid, cpu_id, tid, ret; const struct bt_definition *scope; const char *hostname, *procname; + struct cputime *cpu; + char *from_syscall = NULL; timestamp = bt_ctf_get_timestamp(call_data); @@ -240,7 +243,7 @@ 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_tid || opt_hostname) { + if (opt_tid || opt_hostname || opt_exec_name) { if (!lookup_filter_tid_list(pid)) { /* To display when a process of ours in getting scheduled in */ if (strcmp(bt_ctf_event_name(call_data), "sched_switch") == 0) { @@ -265,6 +268,33 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat cpu_id = get_cpu_id(call_data); procname = get_context_comm(call_data); + if (strncmp(bt_ctf_event_name(call_data), "sys_", 4) == 0) { + cpu = get_cpu(cpu_id); + 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; + } else if ((strncmp(bt_ctf_event_name(call_data), "exit_syscall", 12)) == 0) { + struct tm start_ts; + + 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", + 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, + cpu_id, cpu->current_syscall->name); + if (ret < 0) { + goto error; + } + free(cpu->current_syscall->name); + g_free(cpu->current_syscall); + cpu->current_syscall = NULL; + } + } + if (prev_ts == 0) prev_ts = timestamp; delta = timestamp - prev_ts; @@ -278,7 +308,9 @@ 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(")\n"); + printf(")%s", (from_syscall) ? from_syscall : "\n"); + + free(from_syscall); end: return BT_CB_OK; @@ -525,6 +557,8 @@ void init_lttngtop() global_perf_liszt = g_hash_table_new(g_str_hash, g_str_equal); global_filter_list = g_hash_table_new(g_str_hash, g_str_equal); global_host_list = g_hash_table_new(g_str_hash, g_str_equal); + tid_filter_list = g_hash_table_new(g_str_hash, + g_str_equal); sem_init(&goodtodisplay, 0, 0); sem_init(&goodtoupdate, 0, 1); @@ -647,6 +681,7 @@ static int parse_options(int argc, char **argv) int opt, ret = 0; char *tmp_str; int *tid; + int i; remote_live = 0; @@ -667,8 +702,6 @@ static int parse_options(int argc, char **argv) break; case OPT_PID: toggle_filter = 1; - tid_filter_list = g_hash_table_new(g_str_hash, - g_str_equal); tmp_str = strtok(opt_tid, ","); while (tmp_str) { tid = malloc(sizeof(int)); @@ -717,7 +750,18 @@ static int parse_options(int argc, char **argv) } } - opt_input_path = poptGetArg(pc); + opt_exec_name = NULL; + opt_exec_argv = NULL; + for (i = 0; i < argc; i++) { + if (argv[i][0] == '-' && argv[i][1] == '-') { + opt_exec_name = argv[i + 1]; + opt_exec_argv = &argv[i + 1]; + break; + } + } + if (!opt_exec_name) { + opt_input_path = poptGetArg(pc); + } end: if (pc) { @@ -746,6 +790,10 @@ void iter_trace(struct bt_context *bt_ctx) bt_ctf_iter_add_callback(iter, g_quark_from_static_string("sched_process_fork"), NULL, 0, handle_sched_process_fork, 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); if (opt_textdump) { bt_ctf_iter_add_callback(iter, 0, NULL, 0, print_timestamp, @@ -759,10 +807,6 @@ void iter_trace(struct bt_context *bt_ctx) 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( @@ -805,6 +849,24 @@ void iter_trace(struct bt_context *bt_ctx) } } + if (opt_exec_name) { + pid_t pid; + + pid = fork(); + if (pid == 0) { + execvpe(opt_exec_name, opt_exec_argv, opt_exec_env); + exit(EXIT_SUCCESS); + } else if (pid > 0) { + opt_exec_pid = pid; + g_hash_table_insert(tid_filter_list, + (gpointer) &pid, + &pid); + } else { + perror("fork"); + exit(EXIT_FAILURE); + } + } + while ((event = bt_ctf_iter_read_event(iter)) != NULL) { if (quit || reload_trace) goto end_iter; @@ -1033,11 +1095,19 @@ end: return ret; } -int main(int argc, char **argv) +static void handle_sigchild(int signal) +{ + int status; + + waitpid(opt_exec_pid, &status, 0); +} + +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) { @@ -1048,7 +1118,12 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); } - if (!opt_input_path && !remote_live) { + if (opt_exec_name) { + opt_exec_env = envp; + signal(SIGCHLD, handle_sigchild); + } + + if (!opt_input_path && !remote_live && !opt_exec_name) { /* mmap live */ #ifdef LTTNGTOP_MMAP_LIVE if (opt_textdump) { @@ -1073,18 +1148,6 @@ int main(int argc, char **argv) #endif /* LTTNGTOP_MMAP_LIVE */ } else if (!opt_input_path && remote_live) { /* network live */ -#if 0 - ret = setup_network_live(opt_relay_hostname, opt_begin); - if (ret < 0) { - goto end; - } - - ret = open_trace(&bt_ctx); - if (ret < 0) { - goto end; - } -#endif - bt_ctx = bt_context_create(); ret = bt_context_add_traces_recursive(bt_ctx, opt_relay_hostname, "lttng-live", NULL);