summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
1d74c4d)
Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
char *opt_hostname;
char *opt_relay_hostname;
char *opt_kprobes;
char *opt_hostname;
char *opt_relay_hostname;
char *opt_kprobes;
+char *opt_exec_name;
+char **opt_exec_argv;
+char **opt_exec_env;
+int opt_exec_pid;
GHashTable *tid_filter_list;
int remote_live;
GHashTable *tid_filter_list;
int remote_live;
fprintf(stderr, "Missing tid field\n");
goto error;
}
fprintf(stderr, "Missing tid field\n");
goto error;
}
+ if (tid == opt_exec_pid) {
+ quit = 1;
+ }
death_proc(<tngtop, tid, comm, timestamp);
death_proc(<tngtop, tid, comm, timestamp);
#include <fts.h>
#include <assert.h>
#include <sys/mman.h>
#include <fts.h>
#include <assert.h>
#include <sys/mman.h>
#include <lttng/lttng.h>
#ifdef LTTNGTOP_MMAP_LIVE
#include <lttng/lttngtop-helper.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;
uint64_t delta;
struct tm start;
uint64_t ts_nsec_start;
+ int pid, cpu_id, tid, ret;
const struct bt_definition *scope;
const char *hostname, *procname;
struct cputime *cpu;
const struct bt_definition *scope;
const char *hostname, *procname;
struct cputime *cpu;
tid = get_context_tid(call_data);
hostname = get_context_hostname(call_data);
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 (!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);
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);
" (+%" 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;
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);
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);
sem_init(&goodtodisplay, 0, 0);
sem_init(&goodtoupdate, 0, 1);
int opt, ret = 0;
char *tmp_str;
int *tid;
int opt, ret = 0;
char *tmp_str;
int *tid;
break;
case OPT_PID:
toggle_filter = 1;
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));
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);
+ }
bt_ctf_iter_add_callback(iter,
g_quark_from_static_string("sched_process_fork"),
NULL, 0, handle_sched_process_fork, NULL, NULL, NULL);
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,
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);
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(
/* 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;
while ((event = bt_ctf_iter_read_event(iter)) != NULL) {
if (quit || reload_trace)
goto end_iter;
-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;
{
int ret;
struct bt_context *bt_ctx = NULL;
- 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) {
/* mmap live */
#ifdef LTTNGTOP_MMAP_LIVE
if (opt_textdump) {
#endif /* LTTNGTOP_MMAP_LIVE */
} else if (!opt_input_path && remote_live) {
/* network live */
#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);
bt_ctx = bt_context_create();
ret = bt_context_add_traces_recursive(bt_ctx, opt_relay_hostname,
"lttng-live", NULL);