#include <babeltrace/babeltrace.h>
#include <babeltrace/ctf/events.h>
#include <babeltrace/ctf/callbacks.h>
+#include <babeltrace/ctf/iterator.h>
#include <fcntl.h>
#include <pthread.h>
#include <popt.h>
unsigned int current_display_index = 0;
sem_wait(&bootstrap);
+ /*
+ * Prevent the 1 second delay when we hit ESC
+ */
+ ESCDELAY = 0;
init_ncurses();
while (1) {
ret->visible = 1;
g_hash_table_insert(table, (gpointer) strdup(name), ret);
- global = g_hash_table_lookup(lttngtop.perf_list, (gpointer) name);
+ global = g_hash_table_lookup(global_perf_liszt, (gpointer) name);
if (!global) {
global = g_new0(struct perfcounter, 1);
memcpy(global, ret, sizeof(struct perfcounter));
/* by default, sort on the first perf context */
- if (g_hash_table_size(lttngtop.perf_list) == 0)
+ if (g_hash_table_size(global_perf_liszt) == 0)
global->sort = 1;
- g_hash_table_insert(lttngtop.perf_list, (gpointer) strdup(name), global);
+ g_hash_table_insert(global_perf_liszt, (gpointer) strdup(name), global);
}
end:
}
}
-void extract_perf_counter_scope(struct bt_ctf_event *event,
- struct definition *scope,
+void extract_perf_counter_scope(const struct bt_ctf_event *event,
+ const struct definition *scope,
struct processtop *proc,
struct cputime *cpu)
{
return;
}
-void update_perf_counter(struct processtop *proc, struct bt_ctf_event *event)
+void update_perf_counter(struct processtop *proc, const struct bt_ctf_event *event)
{
struct cputime *cpu;
- struct definition *scope;
+ const struct definition *scope;
cpu = get_cpu(get_cpu_id(event));
void init_lttngtop()
{
copies = g_ptr_array_new();
- lttngtop.perf_list = g_hash_table_new(g_str_hash, g_str_equal);
+ 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(&pause_sem, 0, 1);
sem_init(&end_trace_sem, 0, 0);
+ reset_global_counters();
+ lttngtop.nbproc = 0;
+ lttngtop.nbthreads = 0;
+ lttngtop.nbfiles = 0;
+
lttngtop.process_table = g_ptr_array_new();
lttngtop.files_table = g_ptr_array_new();
lttngtop.cpu_table = g_ptr_array_new();
{
struct bt_ctf_iter *iter;
struct bt_iter_pos begin_pos;
- struct bt_ctf_event *event;
+ const struct bt_ctf_event *event;
int ret = 0;
begin_pos.type = BT_SEEK_BEGIN;
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,
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);
+
while ((event = bt_ctf_iter_read_event(iter)) != NULL) {
ret = bt_iter_next(bt_ctf_get_iter(iter));
if (ret < 0)
sem_wait(&end_trace_sem);
end_iter:
- bt_iter_destroy(bt_ctf_get_iter(iter));
+ bt_ctf_iter_destroy(iter);
}
/*
GArray *trace_ids;
char lpath[PATH_MAX];
char * const paths[2] = { lpath, NULL };
- int ret;
+ int ret = -1;
/*
* Need to copy path, because fts_open can change it.
node->fts_accpath, format_str,
packet_seek, NULL, NULL);
if (trace_id < 0) {
- fprintf(stderr, "[error] [Context] opening trace \"%s\" from %s "
+ fprintf(stderr, "[warning] [Context] opening trace \"%s\" from %s "
"for reading.\n", node->fts_accpath, path);
- ret = trace_id;
- goto error;
+ /* Allow to skip erroneous traces. */
+ continue;
}
g_array_append_val(trace_ids, trace_id);
}
}
g_array_free(trace_ids, TRUE);
- return 0;
+ return ret;
error:
return ret;
}
+static int check_field_requirements(const struct bt_ctf_field_decl *const * field_list,
+ int field_cnt, int *tid_check, int *pid_check,
+ int *procname_check, int *ppid_check)
+{
+ int j;
+
+ for (j = 0; j < field_cnt; j++) {
+ if (*tid_check == 0) {
+ if (strncmp(bt_ctf_get_decl_field_name(field_list[j]), "tid", 3) == 0) {
+ (*tid_check)++;
+ }
+ }
+ if (*pid_check == 0) {
+ if (strncmp(bt_ctf_get_decl_field_name(field_list[j]), "pid", 3) == 0)
+ (*pid_check)++;
+ }
+ if (*ppid_check == 0) {
+ if (strncmp(bt_ctf_get_decl_field_name(field_list[j]), "ppid", 4) == 0)
+ (*ppid_check)++;
+ }
+ if (*procname_check == 0) {
+ if (strncmp(bt_ctf_get_decl_field_name(field_list[j]), "procname", 8) == 0)
+ (*procname_check)++;
+ }
+ }
+ /* if all checks are OK, no need to continue the checks */
+ if (*tid_check == 1 && *pid_check == 1 && *ppid_check == 1 &&
+ *procname_check == 1)
+ return 0;
+
+ return -1;
+}
+
+/*
+ * check_requirements: check if the required context informations are available
+ *
+ * If each mandatory context information is available for at least in one
+ * event, return 0 otherwise return -1.
+ */
+int check_requirements(struct bt_context *ctx)
+{
+ unsigned int i, evt_cnt, field_cnt;
+ struct bt_ctf_event_decl *const * evt_list;
+ const struct bt_ctf_field_decl *const * field_list;
+ int tid_check = 0;
+ int pid_check = 0;
+ int procname_check = 0;
+ int ppid_check = 0;
+ int ret = 0;
+
+ bt_ctf_get_event_decl_list(0, ctx, &evt_list, &evt_cnt);
+ for (i = 0; i < evt_cnt; i++) {
+ bt_ctf_get_decl_fields(evt_list[i], BT_STREAM_EVENT_CONTEXT,
+ &field_list, &field_cnt);
+ ret = check_field_requirements(field_list, field_cnt,
+ &tid_check, &pid_check, &procname_check,
+ &ppid_check);
+ if (ret == 0)
+ goto end;
+
+ bt_ctf_get_decl_fields(evt_list[i], BT_EVENT_CONTEXT,
+ &field_list, &field_cnt);
+ ret = check_field_requirements(field_list, field_cnt,
+ &tid_check, &pid_check, &procname_check,
+ &ppid_check);
+ if (ret == 0)
+ goto end;
+
+ bt_ctf_get_decl_fields(evt_list[i], BT_STREAM_PACKET_CONTEXT,
+ &field_list, &field_cnt);
+ ret = check_field_requirements(field_list, field_cnt,
+ &tid_check, &pid_check, &procname_check,
+ &ppid_check);
+ if (ret == 0)
+ goto end;
+ }
+
+ if (tid_check == 0) {
+ ret = -1;
+ fprintf(stderr, "[error] missing tid context information\n");
+ }
+ if (pid_check == 0) {
+ ret = -1;
+ fprintf(stderr, "[error] missing pid context information\n");
+ }
+ if (ppid_check == 0) {
+ ret = -1;
+ fprintf(stderr, "[error] missing ppid context information\n");
+ }
+ if (procname_check == 0) {
+ ret = -1;
+ fprintf(stderr, "[error] missing procname context information\n");
+ }
+
+end:
+ return ret;
+}
+
int main(int argc, char **argv)
{
int ret;
bt_ctx = bt_context_create();
ret = bt_context_add_traces_recursive(bt_ctx, opt_input_path, "ctf", NULL);
if (ret < 0) {
- printf("[error] Opening the trace\n");
+ fprintf(stderr, "[error] Opening the trace\n");
+ goto end;
+ }
+
+ ret = check_requirements(bt_ctx);
+ if (ret < 0) {
+ fprintf(stderr, "[error] some mandatory contexts were missing, exiting.\n");
goto end;
}