X-Git-Url: https://git.lttng.org/?p=lttngtop.git;a=blobdiff_plain;f=src%2Flttngtop.c;h=6bd7d67e7b65b1b08b07870cabbf1a939e777b8b;hp=6bb03ac760c20c1a3f9daa121475af0c7fd72b70;hb=4553b4d1cec894832e19f5702aa33e107e497365;hpb=d67167cde319ac9d257f5b59b5a4664e558f4cb4 diff --git a/src/lttngtop.c b/src/lttngtop.c index 6bb03ac..6bd7d67 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -10,10 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _GNU_SOURCE @@ -23,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -195,8 +195,8 @@ void update_perf_value(struct processtop *proc, struct cputime *cpu, } } -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) { @@ -213,7 +213,7 @@ void extract_perf_counter_scope(struct bt_ctf_event *event, for (i = 0; i < count; i++) { const char *name = bt_ctf_field_name(list[i]); - if (strncmp(name, "_perf_", 6) == 0) { + if (strncmp(name, "perf_", 5) == 0) { int value = bt_ctf_get_uint64(list[i]); if (bt_ctf_field_get_error()) continue; @@ -225,10 +225,10 @@ end: 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)); @@ -248,7 +248,6 @@ enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, int pid, tid, ppid; char *comm; struct processtop *parent, *child; - struct definition *scope; unsigned long timestamp; /* FIXME : display nice error when missing context pid, tid, ppid and comm */ @@ -257,25 +256,23 @@ enum bt_cb_ret fix_process_table(struct bt_ctf_event *call_data, if (timestamp == -1ULL) goto error; - scope = bt_ctf_get_top_level_scope(call_data, BT_STREAM_EVENT_CONTEXT); - - pid = bt_ctf_get_int64(bt_ctf_get_field(call_data, scope, "_pid")); - if (bt_ctf_field_get_error()) { + pid = get_context_pid(call_data); + if (pid == -1ULL) { // fprintf(stderr, "Missing pid context info\n"); goto error; } - tid = bt_ctf_get_int64(bt_ctf_get_field(call_data, scope, "_tid")); - if (bt_ctf_field_get_error()) { + tid = get_context_tid(call_data); + if (tid == -1ULL) { // fprintf(stderr, "Missing tid context info\n"); goto error; } - ppid = bt_ctf_get_int64(bt_ctf_get_field(call_data, scope, "_ppid")); - if (bt_ctf_field_get_error()) { + ppid = get_context_ppid(call_data); + if (ppid == -1ULL) { // fprintf(stderr, "Missing ppid context info\n"); goto error; } - comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data, scope, "_procname")); - if (bt_ctf_field_get_error()) { + comm = get_context_comm(call_data); + if (!comm) { // fprintf(stderr, "Missing procname context info\n"); goto error; } @@ -319,6 +316,11 @@ void init_lttngtop() 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(); @@ -388,7 +390,7 @@ void iter_trace(struct bt_context *bt_ctx) { 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; @@ -410,6 +412,12 @@ void iter_trace(struct bt_context *bt_ctx) 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, @@ -424,10 +432,15 @@ void iter_trace(struct bt_context *bt_ctx) 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) @@ -438,7 +451,7 @@ void iter_trace(struct bt_context *bt_ctx) sem_wait(&end_trace_sem); end_iter: - bt_iter_destroy(bt_ctf_get_iter(iter)); + bt_ctf_iter_destroy(iter); } /* @@ -535,6 +548,104 @@ 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; @@ -554,7 +665,13 @@ int main(int argc, char **argv) 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] missing mandatory context informations\n"); goto end; }