X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=trunk%2Flttv%2Flttv%2Flttv%2Fstate.c;h=70ca8cbe06286f447bd4f7193be8ccca48c51b9e;hb=27828bc1b0010ee87c2f68e31fb77fd4ae39fa6b;hp=b9bd1416648d6fc3046c8179fa139aa34f939cf1;hpb=3c9fcfb389b04c83ecff34514f5d6eb04cb3eca3;p=lttv.git diff --git a/trunk/lttv/lttv/lttv/state.c b/trunk/lttv/lttv/lttv/state.c index b9bd1416..70ca8cbe 100644 --- a/trunk/lttv/lttv/lttv/state.c +++ b/trunk/lttv/lttv/lttv/state.c @@ -32,6 +32,7 @@ #include #include #include +#include /* Comment : * Mathieu Desnoyers @@ -45,22 +46,35 @@ #define PREALLOCATED_EXECUTION_STACK 10 -/* Facilities Quarks */ +/* Channel Quarks */ GQuark - LTT_FACILITY_KERNEL, - LTT_FACILITY_KERNEL_ARCH, - LTT_FACILITY_LIST, - LTT_FACILITY_FS, - LTT_FACILITY_USER_GENERIC, - LTT_FACILITY_BLOCK, - LTT_FACILITY_STATEDUMP; + LTT_CHANNEL_FD_STATE, + LTT_CHANNEL_GLOBAL_STATE, + LTT_CHANNEL_IRQ_STATE, + LTT_CHANNEL_MODULE_STATE, + LTT_CHANNEL_NETIF_STATE, + LTT_CHANNEL_SOFTIRQ_STATE, + LTT_CHANNEL_SWAP_STATE, + LTT_CHANNEL_SYSCALL_STATE, + LTT_CHANNEL_TASK_STATE, + LTT_CHANNEL_VM_STATE, + LTT_CHANNEL_KPROBE_STATE, + LTT_CHANNEL_FS, + LTT_CHANNEL_KERNEL, + LTT_CHANNEL_MM, + LTT_CHANNEL_USERSPACE, + LTT_CHANNEL_BLOCK; /* Events Quarks */ GQuark LTT_EVENT_SYSCALL_ENTRY, LTT_EVENT_SYSCALL_EXIT, + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY, + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT, + LTT_EVENT_PAGE_FAULT_ENTRY, + LTT_EVENT_PAGE_FAULT_EXIT, LTT_EVENT_TRAP_ENTRY, LTT_EVENT_TRAP_EXIT, LTT_EVENT_IRQ_ENTRY, @@ -83,7 +97,9 @@ GQuark LTT_EVENT_REQUEST_COMPLETE, LTT_EVENT_LIST_INTERRUPT, LTT_EVENT_SYS_CALL_TABLE, - LTT_EVENT_SOFTIRQ_VEC; + LTT_EVENT_SOFTIRQ_VEC, + LTT_EVENT_KPROBE_TABLE, + LTT_EVENT_KPROBE; /* Fields Quarks */ @@ -114,7 +130,8 @@ GQuark LTT_FIELD_ACTION, LTT_FIELD_ID, LTT_FIELD_ADDRESS, - LTT_FIELD_SYMBOL; + LTT_FIELD_SYMBOL, + LTT_FIELD_IP; LttvExecutionMode LTTV_STATE_MODE_UNKNOWN, @@ -210,6 +227,23 @@ static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data); static LttvBdevState *bdevstate_copy(LttvBdevState *bds); +#if (__SIZEOF_LONG__ == 4) +guint guint64_hash(gconstpointer key) +{ + guint64 ukey = *(const guint64 *)key; + + return (guint)ukey ^ (guint)(ukey >> 32); +} + +gboolean guint64_equal(gconstpointer a, gconstpointer b) +{ + guint64 ua = *(const guint64 *)a; + guint64 ub = *(const guint64 *)b; + + return ua == ub; +} +#endif + void lttv_state_save(LttvTraceState *self, LttvAttribute *container) { LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container); @@ -309,6 +343,18 @@ static void expand_syscall_table(LttvTraceState *ts, int id) ts->nb_syscalls = new_nb; } +static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol) +{ +#if (__SIZEOF_LONG__ == 4) + guint64 *ip_ptr = g_new(guint64, 1); + g_hash_table_insert(ts->kprobe_hash, ip_ptr, + (gpointer)(glong)g_quark_from_string(symbol)); +#else + g_hash_table_insert(ts->kprobe_hash, (gpointer)ip, + (gpointer)(glong)g_quark_from_string(symbol)); +#endif +} + static void expand_trap_table(LttvTraceState *ts, int id) { guint new_nb = check_expand(ts->nb_traps, id); @@ -421,9 +467,12 @@ restore_init_state(LttvTraceState *self) /* reset cpu states */ if(self->cpu_states[i].mode_stack->len > 0) { g_array_remove_range(self->cpu_states[i].mode_stack, 0, self->cpu_states[i].mode_stack->len); - self->cpu_states[i].last_irq = -1; - self->cpu_states[i].last_soft_irq = -1; - self->cpu_states[i].last_trap = -1; + if(self->cpu_states[i].irq_stack->len) + g_array_remove_range(self->cpu_states[i].irq_stack, 0, self->cpu_states[i].irq_stack->len); + if(self->cpu_states[i].softirq_stack->len) + g_array_remove_range(self->cpu_states[i].softirq_stack, 0, self->cpu_states[i].softirq_stack->len); + if(self->cpu_states[i].trap_stack->len) + g_array_remove_range(self->cpu_states[i].trap_stack, 0, self->cpu_states[i].trap_stack->len); } } @@ -603,9 +652,9 @@ init(LttvTracesetState *self, LttvTraceset *ts) tcs->cpu_states = g_new(LttvCPUState, nb_cpu); for(j = 0; jcpu_states[j].mode_stack = g_array_new(FALSE, FALSE, sizeof(LttvCPUMode)); - tcs->cpu_states[j].last_irq = -1; - tcs->cpu_states[j].last_soft_irq = -1; - tcs->cpu_states[j].last_trap = -1; + tcs->cpu_states[j].irq_stack = g_array_new(FALSE, FALSE, sizeof(gint)); + tcs->cpu_states[j].softirq_stack = g_array_new(FALSE, FALSE, sizeof(gint)); + tcs->cpu_states[j].trap_stack = g_array_new(FALSE, FALSE, sizeof(gint)); g_assert(tcs->cpu_states[j].mode_stack != NULL); } @@ -638,12 +687,12 @@ init(LttvTracesetState *self, LttvTraceset *ts) /* It's a Usertrace */ guint tid = ltt_tracefile_tid(tfcs->parent.tf); GTree *usertrace_tree = (GTree*)g_hash_table_lookup(tcs->usertraces, - (gconstpointer)tid); + GUINT_TO_POINTER(tid)); if(!usertrace_tree) { usertrace_tree = g_tree_new_full(compare_usertraces, NULL, free_usertrace_key, NULL); g_hash_table_insert(tcs->usertraces, - (gpointer)tid, usertrace_tree); + GUINT_TO_POINTER(tid), usertrace_tree); } LttTime *timestamp = g_new(LttTime, 1); *timestamp = ltt_interpolate_time_from_tsc(tfcs->parent.tf, @@ -753,7 +802,7 @@ static void write_process_state(gpointer key, gpointer value, for(i = 0 ; i < process->user_stack->len; i++) { address = g_array_index(process->user_stack, guint64, i); - fprintf(fp, " \n", + fprintf(fp, " \n", address); } @@ -807,7 +856,7 @@ void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp) else { ltt_event_position(e, ep); ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc); - fprintf(fp, " BLOCK=%u OFFSET=%u TSC=%llu/>\n", nb_block, offset, + fprintf(fp, " BLOCK=%u OFFSET=%u TSC=%" PRIu64 "/>\n", nb_block, offset, tsc); } } @@ -1282,10 +1331,25 @@ static LttvCPUState *lttv_state_copy_cpu_states(LttvCPUState *states, guint n) retval = g_new(LttvCPUState, n); for(i=0; ilen); + for(j=0; jlen; j++) { + g_array_index(retval[i].irq_stack, gint, j) = g_array_index(states[i].irq_stack, gint, j); + } + + retval[i].softirq_stack = g_array_new(FALSE, FALSE, sizeof(gint)); + g_array_set_size(retval[i].softirq_stack, states[i].softirq_stack->len); + for(j=0; jlen; j++) { + g_array_index(retval[i].softirq_stack, gint, j) = g_array_index(states[i].softirq_stack, gint, j); + } + + retval[i].trap_stack = g_array_new(FALSE, FALSE, sizeof(gint)); + g_array_set_size(retval[i].trap_stack, states[i].trap_stack->len); + for(j=0; jlen; j++) { + g_array_index(retval[i].trap_stack, gint, j) = g_array_index(states[i].trap_stack, gint, j); + } + retval[i].mode_stack = g_array_new(FALSE, FALSE, sizeof(LttvCPUMode)); - retval[i].last_irq = states[i].last_irq; - retval[i].last_soft_irq = states[i].last_soft_irq; - retval[i].last_trap = states[i].last_trap; g_array_set_size(retval[i].mode_stack, states[i].mode_stack->len); for(j=0; jlen; j++) { g_array_index(retval[i].mode_stack, GQuark, j) = g_array_index(states[i].mode_stack, GQuark, j); @@ -1301,6 +1365,9 @@ static void lttv_state_free_cpu_states(LttvCPUState *states, guint n) for(i=0; iparent.timestamp.tv_sec, tfcs->parent.timestamp.tv_nsec); } @@ -1852,6 +1919,7 @@ typedef struct _LttvNameTables { guint nb_irqs; GQuark *soft_irq_names; guint nb_softirqs; + GHashTable *kprobe_hash; } LttvNameTables; @@ -1876,7 +1944,7 @@ create_name_tables(LttvTraceState *tcs) hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 1); if(!lttv_trace_find_hook(tcs->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SYSCALL_ENTRY, FIELD_ARRAY(LTT_FIELD_SYSCALL_ID), NULL, NULL, &hooks)) { @@ -1912,9 +1980,14 @@ create_name_tables(LttvTraceState *tcs) lttv_trace_hook_remove_all(&hooks); if(!lttv_trace_find_hook(tcs->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_TRAP_ENTRY, FIELD_ARRAY(LTT_FIELD_TRAP_ID), + NULL, NULL, &hooks) || + !lttv_trace_find_hook(tcs->parent.t, + LTT_CHANNEL_KERNEL, + LTT_EVENT_PAGE_FAULT_ENTRY, + FIELD_ARRAY(LTT_FIELD_TRAP_ID), NULL, NULL, &hooks)) { // th = lttv_trace_hook_get_first(&th); @@ -1941,7 +2014,7 @@ create_name_tables(LttvTraceState *tcs) lttv_trace_hook_remove_all(&hooks); if(!lttv_trace_find_hook(tcs->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_IRQ_ENTRY, FIELD_ARRAY(LTT_FIELD_IRQ_ID), NULL, NULL, &hooks)) { @@ -1981,6 +2054,13 @@ create_name_tables(LttvTraceState *tcs) g_array_free(hooks, TRUE); g_string_free(fe_name, TRUE); + +#if (__SIZEOF_LONG__ == 4) + name_tables->kprobe_hash = g_hash_table_new_full(guint64_hash, guint64_equal, + g_free, NULL); +#else + name_tables->kprobe_hash = g_hash_table_new(g_direct_hash, g_direct_equal); +#endif } @@ -2004,6 +2084,7 @@ get_name_tables(LttvTraceState *tcs) tcs->soft_irq_names = name_tables->soft_irq_names; tcs->nb_irqs = name_tables->nb_irqs; tcs->nb_soft_irqs = name_tables->nb_softirqs; + tcs->kprobe_hash = name_tables->kprobe_hash; } @@ -2025,6 +2106,7 @@ free_name_tables(LttvTraceState *tcs) if(name_tables->irq_names) g_free(name_tables->irq_names); if(name_tables->soft_irq_names) g_free(name_tables->soft_irq_names); if(name_tables) g_free(name_tables); + if(name_tables) g_hash_table_destroy(name_tables->kprobe_hash); } #ifdef HASH_TABLE_DEBUG @@ -2234,7 +2316,8 @@ static LttvTracefileState *ltt_state_usertrace_find(LttvTraceState *tcs, * timestamp the lowest, but higher or equal to "timestamp". */ res.time = timestamp; res.best = NULL; - GTree *usertrace_tree = g_hash_table_lookup(tcs->usertraces, (gpointer)pid); + GTree *usertrace_tree = g_hash_table_lookup(tcs->usertraces, + GUINT_TO_POINTER(pid)); if(usertrace_tree) { g_tree_search(usertrace_tree, search_usertrace, &res); if(res.best) @@ -2455,7 +2538,7 @@ static gboolean trap_entry(void *hook_data, void *call_data) cpu_push_mode(s->cpu_state, LTTV_CPU_TRAP); /* update trap status */ - s->cpu_state->last_trap = trap; + g_array_append_val(s->cpu_state->trap_stack, trap); ts->trap_states[trap].running++; return FALSE; @@ -2465,7 +2548,6 @@ static gboolean trap_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; - gint trap = s->cpu_state->last_trap; pop_state(s, LTTV_STATE_TRAP); @@ -2473,10 +2555,12 @@ static gboolean trap_exit(void *hook_data, void *call_data) cpu_pop_mode(s->cpu_state); /* update trap status */ - if (trap != -1) - if(ts->trap_states[trap].running) - ts->trap_states[trap].running--; - + if (s->cpu_state->trap_stack->len > 0) { + gint last = g_array_index(s->cpu_state->trap_stack, gint, s->cpu_state->trap_stack->len-1); + if(ts->trap_states[last].running) + ts->trap_states[last].running--; + g_array_remove_index(s->cpu_state->trap_stack, s->cpu_state->trap_stack->len-1); + } return FALSE; } @@ -2503,7 +2587,7 @@ static gboolean irq_entry(void *hook_data, void *call_data) cpu_push_mode(s->cpu_state, LTTV_CPU_IRQ); /* update irq status */ - s->cpu_state->last_irq = irq; + g_array_append_val(s->cpu_state->irq_stack, irq); irq_push_mode(&ts->irq_states[irq], LTTV_IRQ_BUSY); return FALSE; @@ -2513,18 +2597,19 @@ static gboolean soft_irq_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; - gint softirq = s->cpu_state->last_soft_irq; pop_state(s, LTTV_STATE_SOFT_IRQ); - /* update softirq status */ - if (softirq != -1) - if(ts->soft_irq_states[softirq].running) - ts->soft_irq_states[softirq].running--; - /* update cpu status */ cpu_pop_mode(s->cpu_state); + /* update softirq status */ + if (s->cpu_state->softirq_stack->len > 0) { + gint last = g_array_index(s->cpu_state->softirq_stack, gint, s->cpu_state->softirq_stack->len-1); + if(ts->soft_irq_states[last].running) + ts->soft_irq_states[last].running--; + g_array_remove_index(s->cpu_state->softirq_stack, s->cpu_state->softirq_stack->len-1); + } return FALSE; } @@ -2539,8 +2624,11 @@ static gboolean irq_exit(void *hook_data, void *call_data) cpu_pop_mode(s->cpu_state); /* update irq status */ - if (s->cpu_state->last_irq != -1) - irq_pop_mode(&ts->irq_states[s->cpu_state->last_irq]); + if (s->cpu_state->irq_stack->len > 0) { + gint last = g_array_index(s->cpu_state->irq_stack, gint, s->cpu_state->irq_stack->len-1); + g_array_remove_index(s->cpu_state->irq_stack, s->cpu_state->irq_stack->len-1); + irq_pop_mode(&ts->irq_states[last]); + } return FALSE; } @@ -2563,7 +2651,7 @@ static gboolean soft_irq_raise(void *hook_data, void *call_data) } else { /* Fixup an incomplete irq table */ GString *string = g_string_new(""); - g_string_printf(string, "softirq %llu", softirq); + g_string_printf(string, "softirq %" PRIu64, softirq); submode = g_quark_from_string(string->str); g_string_free(string, TRUE); } @@ -2595,7 +2683,7 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) cpu_push_mode(s->cpu_state, LTTV_CPU_SOFT_IRQ); /* update softirq status */ - s->cpu_state->last_soft_irq = softirq; + g_array_append_val(s->cpu_state->softirq_stack, softirq); if(ts->soft_irq_states[softirq].pending) ts->soft_irq_states[softirq].pending--; ts->soft_irq_states[softirq].running++; @@ -2700,7 +2788,7 @@ static void pop_function(LttvTracefileState *tfs, guint64 funcptr) if(process->current_function != funcptr){ g_info("Different functions (%lu.%09lu): ignore it\n", tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); - g_info("process state has %llu when pop_function is %llu\n", + g_info("process state has %" PRIu64 " when pop_function is %" PRIu64 "\n", process->current_function, funcptr); g_info("{ %u, %u, %s, %s, %s }\n", process->pid, @@ -2771,6 +2859,23 @@ static gboolean dump_syscall(void *hook_data, void *call_data) return FALSE; } +static gboolean dump_kprobe(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState*)s->parent.t_context; + LttEvent *e = ltt_tracefile_get_event(s->parent.tf); + LttvTraceHook *th = (LttvTraceHook *)hook_data; + guint64 ip; + char *symbol; + + ip = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 0)); + symbol = ltt_event_get_string(e, lttv_trace_get_hook_field(th, 1)); + + expand_kprobe_table(ts, ip, symbol); + + return FALSE; +} + static gboolean dump_softirq(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; @@ -2947,7 +3052,16 @@ static gboolean process_fork(void *hook_data, void *call_data) * * Simply put a correct parent. */ - g_error("Process %u has been created before fork on cpu %u. Probably an unsynchronized TSC problem on the traced machine.", child_pid, cpu); + g_error("Process %u has been created at [%lu.%09lu] " + "and inserted at [%lu.%09lu] before \n" + "fork on cpu %u[%lu.%09lu].\n" + "Probably an unsynchronized TSC problem on the traced machine.", + child_pid, + child_process->creation_time.tv_sec, + child_process->creation_time.tv_nsec, + child_process->insertion_time.tv_sec, + child_process->insertion_time.tv_nsec, + cpu, ltt_event_time(e).tv_sec, ltt_event_time(e).tv_nsec); //g_assert(0); /* This is a problematic case : the process has been created // before the fork event */ child_process->ppid = process->pid; @@ -3374,111 +3488,135 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) /* Find the eventtype id for the following events and register the associated by id hooks. */ - hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 19); + hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 20); //hooks = g_array_set_size(hooks, 19); // Max possible number of hooks. //hn = 0; lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SYSCALL_ENTRY, FIELD_ARRAY(LTT_FIELD_SYSCALL_ID), syscall_entry, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SYSCALL_EXIT, NULL, syscall_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_TRAP_ENTRY, FIELD_ARRAY(LTT_FIELD_TRAP_ID), trap_entry, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_TRAP_EXIT, NULL, trap_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, + LTT_EVENT_PAGE_FAULT_ENTRY, + FIELD_ARRAY(LTT_FIELD_TRAP_ID), + trap_entry, NULL, &hooks); + + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_KERNEL, + LTT_EVENT_PAGE_FAULT_EXIT, + NULL, + trap_exit, NULL, &hooks); + + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_KERNEL, + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY, + FIELD_ARRAY(LTT_FIELD_TRAP_ID), + trap_entry, NULL, &hooks); + + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_KERNEL, + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT, + NULL, + trap_exit, NULL, &hooks); + + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_KERNEL, LTT_EVENT_IRQ_ENTRY, FIELD_ARRAY(LTT_FIELD_IRQ_ID), irq_entry, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_IRQ_EXIT, NULL, irq_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SOFT_IRQ_RAISE, FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID), soft_irq_raise, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY, FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID), soft_irq_entry, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT, NULL, soft_irq_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_SCHED_SCHEDULE, FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE), schedchange, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_PROCESS_FORK, FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, LTT_FIELD_CHILD_TGID), process_fork, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL_ARCH, + LTT_CHANNEL_KERNEL, LTT_EVENT_KTHREAD_CREATE, FIELD_ARRAY(LTT_FIELD_PID), process_kernel_thread, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_PROCESS_EXIT, FIELD_ARRAY(LTT_FIELD_PID), process_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_KERNEL, + LTT_CHANNEL_KERNEL, LTT_EVENT_PROCESS_FREE, FIELD_ARRAY(LTT_FIELD_PID), process_free, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_FS, + LTT_CHANNEL_FS, LTT_EVENT_EXEC, FIELD_ARRAY(LTT_FIELD_FILENAME), process_exec, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_USER_GENERIC, + LTT_CHANNEL_USERSPACE, LTT_EVENT_THREAD_BRAND, FIELD_ARRAY(LTT_FIELD_NAME), thread_brand, NULL, &hooks); /* statedump-related hooks */ lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_LIST, + LTT_CHANNEL_TASK_STATE, LTT_EVENT_PROCESS_STATE, FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME, LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, @@ -3486,49 +3624,55 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) enum_process_state, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_LIST, + LTT_CHANNEL_GLOBAL_STATE, LTT_EVENT_STATEDUMP_END, NULL, statedump_end, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_LIST, + LTT_CHANNEL_IRQ_STATE, LTT_EVENT_LIST_INTERRUPT, FIELD_ARRAY(LTT_FIELD_ACTION, LTT_FIELD_IRQ_ID), enum_interrupt, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_BLOCK, + LTT_CHANNEL_BLOCK, LTT_EVENT_REQUEST_ISSUE, FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION), bdev_request_issue, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_BLOCK, + LTT_CHANNEL_BLOCK, LTT_EVENT_REQUEST_COMPLETE, FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION), bdev_request_complete, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_USER_GENERIC, + LTT_CHANNEL_USERSPACE, LTT_EVENT_FUNCTION_ENTRY, FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE), function_entry, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_USER_GENERIC, + LTT_CHANNEL_USERSPACE, LTT_EVENT_FUNCTION_EXIT, FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE), function_exit, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_STATEDUMP, + LTT_CHANNEL_SYSCALL_STATE, LTT_EVENT_SYS_CALL_TABLE, FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL), dump_syscall, NULL, &hooks); lttv_trace_find_hook(ts->parent.t, - LTT_FACILITY_STATEDUMP, + LTT_CHANNEL_KPROBE_STATE, + LTT_EVENT_KPROBE_TABLE, + FIELD_ARRAY(LTT_FIELD_IP, LTT_FIELD_SYMBOL), + dump_kprobe, NULL, &hooks); + + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_SOFTIRQ_STATE, LTT_EVENT_SOFTIRQ_VEC, FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL), dump_softirq, NULL, &hooks); @@ -3544,11 +3688,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) for(k = 0 ; k < hooks->len ; k++) { th = &g_array_index(hooks, LttvTraceHook, k); - lttv_hooks_add( - lttv_hooks_by_id_find(tfs->parent.event_by_id, th->id), - th->h, - th, - LTTV_PRIO_STATE); + if (th->mdata == tfs->parent.tf->mdata) + lttv_hooks_add( + lttv_hooks_by_id_find(tfs->parent.event_by_id, th->id), + th->h, + th, + LTTV_PRIO_STATE); } } lttv_attribute_find(ts->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); @@ -3599,6 +3744,7 @@ void lttv_state_remove_event_hooks(LttvTracesetState *self) for(k = 0 ; k < hooks->len ; k++) { th = &g_array_index(hooks, LttvTraceHook, k); + if (th->mdata == tfs->parent.tf->mdata) lttv_hooks_remove_data( lttv_hooks_by_id_find(tfs->parent.event_by_id, th->id), th->h, @@ -3938,7 +4084,7 @@ void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) gboolean is_named; - LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree; + LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree = NULL; //g_tree_destroy(self->parent.pqueue); //self->parent.pqueue = g_tree_new(compare_tracefile); @@ -4189,19 +4335,31 @@ static void module_init() LTTV_STATE_RESOURCE_TRAPS = g_quark_from_string("trap resource states"); LTTV_STATE_RESOURCE_BLKDEVS = g_quark_from_string("blkdevs resource states"); - - LTT_FACILITY_KERNEL = g_quark_from_string("kernel"); - LTT_FACILITY_KERNEL_ARCH = g_quark_from_string("kernel_arch"); - LTT_FACILITY_FS = g_quark_from_string("fs"); - LTT_FACILITY_LIST = g_quark_from_string("list"); - LTT_FACILITY_USER_GENERIC = g_quark_from_string("user_generic"); - LTT_FACILITY_BLOCK = g_quark_from_string("block"); - LTT_FACILITY_STATEDUMP = g_quark_from_string("statedump"); - + LTT_CHANNEL_FD_STATE = g_quark_from_string("fd_state"); + LTT_CHANNEL_GLOBAL_STATE = g_quark_from_string("global_state"); + LTT_CHANNEL_IRQ_STATE = g_quark_from_string("irq_state"); + LTT_CHANNEL_MODULE_STATE = g_quark_from_string("module_state"); + LTT_CHANNEL_NETIF_STATE = g_quark_from_string("netif_state"); + LTT_CHANNEL_SOFTIRQ_STATE = g_quark_from_string("softirq_state"); + LTT_CHANNEL_SWAP_STATE = g_quark_from_string("swap_state"); + LTT_CHANNEL_SYSCALL_STATE = g_quark_from_string("syscall_state"); + LTT_CHANNEL_TASK_STATE = g_quark_from_string("task_state"); + LTT_CHANNEL_VM_STATE = g_quark_from_string("vm_state"); + LTT_CHANNEL_KPROBE_STATE = g_quark_from_string("kprobe_state"); + LTT_CHANNEL_FS = g_quark_from_string("fs"); + LTT_CHANNEL_KERNEL = g_quark_from_string("kernel"); + LTT_CHANNEL_MM = g_quark_from_string("mm"); + LTT_CHANNEL_USERSPACE = g_quark_from_string("userspace"); + LTT_CHANNEL_BLOCK = g_quark_from_string("block"); + LTT_EVENT_SYSCALL_ENTRY = g_quark_from_string("syscall_entry"); LTT_EVENT_SYSCALL_EXIT = g_quark_from_string("syscall_exit"); LTT_EVENT_TRAP_ENTRY = g_quark_from_string("trap_entry"); LTT_EVENT_TRAP_EXIT = g_quark_from_string("trap_exit"); + LTT_EVENT_PAGE_FAULT_ENTRY = g_quark_from_string("page_fault_entry"); + LTT_EVENT_PAGE_FAULT_EXIT = g_quark_from_string("page_fault_exit"); + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY = g_quark_from_string("page_fault_nosem_entry"); + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT = g_quark_from_string("page_fault_nosem_exit"); LTT_EVENT_IRQ_ENTRY = g_quark_from_string("irq_entry"); LTT_EVENT_IRQ_EXIT = g_quark_from_string("irq_exit"); LTT_EVENT_SOFT_IRQ_RAISE = g_quark_from_string("softirq_raise"); @@ -4223,6 +4381,8 @@ static void module_init() LTT_EVENT_LIST_INTERRUPT = g_quark_from_string("interrupt"); LTT_EVENT_SYS_CALL_TABLE = g_quark_from_string("sys_call_table"); LTT_EVENT_SOFTIRQ_VEC = g_quark_from_string("softirq_vec"); + LTT_EVENT_KPROBE_TABLE = g_quark_from_string("kprobe_table"); + LTT_EVENT_KPROBE = g_quark_from_string("kprobe"); LTT_FIELD_SYSCALL_ID = g_quark_from_string("syscall_id"); LTT_FIELD_TRAP_ID = g_quark_from_string("trap_id"); @@ -4251,6 +4411,7 @@ static void module_init() LTT_FIELD_ID = g_quark_from_string("id"); LTT_FIELD_ADDRESS = g_quark_from_string("address"); LTT_FIELD_SYMBOL = g_quark_from_string("symbol"); + LTT_FIELD_IP = g_quark_from_string("ip"); LTTV_CPU_UNKNOWN = g_quark_from_string("unknown"); LTTV_CPU_IDLE = g_quark_from_string("idle");