convert from svn repository: remove tags directory
[lttv.git] / trunk / lttv / lttv / lttv / state.c
index b9bd1416648d6fc3046c8179fa139aa34f939cf1..70ca8cbe06286f447bd4f7193be8ccca48c51b9e 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <ltt/ltt-private.h>
+#include <inttypes.h>
 
 /* Comment :
  * Mathieu Desnoyers
 
 #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; j<nb_cpu; j++) {
       tcs->cpu_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, "    <USER_STACK ADDRESS=\"%llu\"/>\n",
+    fprintf(fp, "    <USER_STACK ADDRESS=\"%" PRIu64 "\"/>\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; i<n; i++) {
+    retval[i].irq_stack = g_array_new(FALSE, FALSE, sizeof(gint));
+    g_array_set_size(retval[i].irq_stack, states[i].irq_stack->len);
+    for(j=0; j<states[i].irq_stack->len; 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; j<states[i].softirq_stack->len; 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; j<states[i].trap_stack->len; 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; j<states[i].mode_stack->len; 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; i<n; i++) {
     g_array_free(states[i].mode_stack, TRUE);
+    g_array_free(states[i].irq_stack, TRUE);
+    g_array_free(states[i].softirq_stack, TRUE);
+    g_array_free(states[i].trap_stack, TRUE);
   }
 
   g_free(states);
@@ -1528,7 +1595,7 @@ static void state_save(LttvTraceState *self, LttvAttribute *container)
       guint64 tsc;
       LttTracefile *tf;
       ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc);
-      g_info("Block %u offset %u tsc %llu time %lu.%lu", nb_block, offset,
+      g_info("Block %u offset %u tsc %" PRIu64 " time %lu.%lu", nb_block, offset,
           tsc,
           tfcs->parent.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");
This page took 0.031779 seconds and 4 git commands to generate.