X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=trunk%2Flttv%2Flttv%2Flttv%2Fstate.c;h=52c8ea6b963bec3e0a983b23173849a14db1b89f;hb=9ee1ff6aafc917b69d1510dad5a7e100d47debc4;hp=e6278ac8070bccba3d3a504326fda047c8ec0978;hpb=43ed82b5b0a7de73d473ec7e6f8802e18d729ec3;p=lttv.git diff --git a/trunk/lttv/lttv/lttv/state.c b/trunk/lttv/lttv/lttv/state.c index e6278ac8..52c8ea6b 100644 --- a/trunk/lttv/lttv/lttv/state.c +++ b/trunk/lttv/lttv/lttv/state.c @@ -59,6 +59,7 @@ GQuark 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, @@ -70,6 +71,10 @@ GQuark 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, @@ -92,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 */ @@ -123,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, @@ -219,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); @@ -318,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); @@ -1861,6 +1898,7 @@ typedef struct _LttvNameTables { guint nb_irqs; GQuark *soft_irq_names; guint nb_softirqs; + GHashTable *kprobe_hash; } LttvNameTables; @@ -1990,6 +2028,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 } @@ -2013,6 +2058,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; } @@ -2034,6 +2080,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 @@ -2781,6 +2828,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; @@ -3393,7 +3457,7 @@ 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; @@ -3421,6 +3485,30 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) NULL, trap_exit, NULL, &hooks); + lttv_trace_find_hook(ts->parent.t, + 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, @@ -3546,6 +3634,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL), dump_syscall, NULL, &hooks); + lttv_trace_find_hook(ts->parent.t, + 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, @@ -4220,6 +4314,7 @@ static void module_init() 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"); @@ -4230,6 +4325,10 @@ static void module_init() 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"); @@ -4251,6 +4350,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"); @@ -4279,6 +4380,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");