#include <fts.h>
#include <assert.h>
#include <sys/mman.h>
+#include <sys/wait.h>
#include <lttng/lttng.h>
#ifdef LTTNGTOP_MMAP_LIVE
#include <lttng/lttngtop-helper.h>
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;
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) {
if (cpu->current_syscall) {
delta = timestamp - cpu->current_syscall->ts_start;
start_ts = format_timestamp(cpu->current_syscall->ts_start);
- asprintf(&from_syscall, " [from %02d:%02d:%02d.%09" PRIu64
+ 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;
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);
int opt, ret = 0;
char *tmp_str;
int *tid;
+ int i;
remote_live = 0;
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));
}
}
- 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) {
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,
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(
}
}
+ 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;
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;
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) {
#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);