state.c: fix statedump end fixup, add "print_stack()" helper
[lttv.git] / lttv / lttv / state.c
index 1a245500f8995ea7e211ab071e78f22a2fff6e86..25af4116000fc457adf4d7eff7f1d11b0f942bbd 100644 (file)
@@ -136,7 +136,9 @@ GQuark
     LTT_FIELD_ADDRESS,
     LTT_FIELD_SYMBOL,
     LTT_FIELD_IP,
-    LTT_FIELD_FD;
+    LTT_FIELD_FD,
+    LTT_FIELD_STATE,
+    LTT_FIELD_CPU_ID;
 
 LttvExecutionMode
   LTTV_STATE_MODE_UNKNOWN,
@@ -232,7 +234,7 @@ static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data);
 static LttvBdevState *bdevstate_copy(LttvBdevState *bds);
 
 
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
 guint guint64_hash(gconstpointer key)
 {
        guint64 ukey = *(const guint64 *)key;
@@ -355,7 +357,7 @@ static void expand_syscall_table(LttvTraceState *ts, int id)
 static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol)
 {
   LttvNameTables *nt = ts->name_tables;
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
   guint64 *ip_ptr = g_new(guint64, 1);
   g_hash_table_insert(nt->kprobe_hash, ip_ptr,
     (gpointer)(glong)g_quark_from_string(symbol));
@@ -1707,6 +1709,7 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container)
   LttEventPosition *ep;
 
   LttvTracesetContext *tsc = self->parent.ts_context;
+  int retval;
 
   tracefiles_tree = lttv_attribute_find_subdir(container, 
       LTTV_STATE_TRACEFILES);
@@ -1794,9 +1797,10 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container)
     g_tree_remove(tsc->pqueue, tfc);
     
     if(ep != NULL) {
-      g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
+      retval= ltt_tracefile_seek_position(tfc->tf, ep);
+      g_assert_cmpint(retval, ==, 0);
       tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf));
-      g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0);
+      g_assert_cmpint(ltt_time_compare(tfc->timestamp, ltt_time_infinite), !=, 0);
       g_tree_insert(tsc->pqueue, tfc, tfc);
       g_info("Restoring state for a tf at time %lu.%lu", tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
     } else {
@@ -2053,10 +2057,12 @@ create_name_tables(LttvTraceState *tcs)
       name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
     }
     */
+    /* FIXME: LttvIRQState *irq_states should become a g_array */
+    /* temp fix: increase from 256 to 512 default size */
 
-    name_tables->nb_irqs = 256;
-    name_tables->irq_names = g_new(GQuark, 256);
-    for(i = 0 ; i < 256 ; i++) {
+    name_tables->nb_irqs = 512;
+    name_tables->irq_names = g_new(GQuark, 512);
+    for(i = 0 ; i < 512 ; i++) {
       g_string_printf(fe_name, "irq %d", i);
       name_tables->irq_names[i] = g_quark_from_string(fe_name->str);
     }
@@ -2083,7 +2089,7 @@ create_name_tables(LttvTraceState *tcs)
 
   g_string_free(fe_name, TRUE);
 
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
   name_tables->kprobe_hash = g_hash_table_new_full(guint64_hash, guint64_equal,
     g_free, NULL);
 #else
@@ -2931,6 +2937,30 @@ static gboolean dump_softirq(void *hook_data, void *call_data)
   return FALSE;
 }
 
+static gboolean sched_try_wakeup(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHook *th = (LttvTraceHook *)hook_data;
+  LttvProcessState *process;
+  gint woken_pid;
+  guint woken_cpu;
+
+  woken_pid = ltt_event_get_int(e, lttv_trace_get_hook_field(th, 0));
+  woken_cpu = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 1));
+
+  process = lttv_state_find_process_or_create(
+                  (LttvTraceState*)s->parent.t_context,
+                  woken_cpu, woken_pid,
+                  &s->parent.timestamp);
+  process->state->s = LTTV_STATE_WAIT_CPU;
+  process->state->change = s->parent.timestamp;
+
+  g_debug("Wakeup: process %d on CPU %u\n", woken_pid, woken_cpu);
+
+  return FALSE;
+}
+
 static gboolean schedchange(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
@@ -3283,6 +3313,25 @@ static gboolean fs_open(void *hook_data, void *call_data)
   return FALSE;
 }
 
+static void print_stack(LttvProcessState *process)
+{
+       LttvExecutionState *es;
+       int i;
+
+       g_debug("Execution stack for process %u %s:\n",
+               process->pid, g_quark_to_string(process->name));
+
+       for (i = 0; i < process->execution_stack->len; i++) {
+               es = &g_array_index(process->execution_stack,
+                                   LttvExecutionState, i);
+               g_debug("Depth %d mode %s submode %s status %s\n",
+                       i, g_quark_to_string(es->t),
+                       g_quark_to_string(es->n),
+                       g_quark_to_string(es->s));
+       }
+
+}
+
 static void fix_process(gpointer key, gpointer value,
    gpointer user_data)
 {
@@ -3291,6 +3340,8 @@ static void fix_process(gpointer key, gpointer value,
   process = (LttvProcessState *)value;
   LttTime *timestamp = (LttTime*)user_data;
 
+  print_stack(process);
+
   if(process->type == LTTV_STATE_KERNEL_THREAD) {
     es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
     if(es->t == LTTV_STATE_MODE_UNKNOWN) {
@@ -3315,21 +3366,28 @@ static void fix_process(gpointer key, gpointer value,
         es->s = LTTV_STATE_RUN;
 
       if(process->execution_stack->len == 1) {
-        /* Still in bottom unknown mode, means never did a system call
+        /* Still in bottom unknown mode, means we either:
+        * - never did a system call
+        * - are scheduled out from user mode.
         * May be either in user mode, syscall mode, running or waiting.*/
-       /* FIXME : we may be tagging syscall mode when being user mode */
-        process->execution_stack =
-          g_array_set_size(process->execution_stack, 2);
-        es = process->state = &g_array_index(process->execution_stack, 
-          LttvExecutionState, 1);
-        es->t = LTTV_STATE_SYSCALL;
-        es->n = LTTV_STATE_SUBMODE_NONE;
-        es->entry = *timestamp;
-        //g_assert(timestamp->tv_sec != 0);
-        es->change = *timestamp;
-        es->cum_cpu_time = ltt_time_zero;
-       if(es->s == LTTV_STATE_WAIT_FORK)
-          es->s = LTTV_STATE_WAIT;
+       /* CHECK : we may be tagging syscall mode when being user mode
+        * (should be fixed now) */
+       if (es->s == LTTV_STATE_WAIT_CPU) {
+               /* nothing to do: scheduled out from userspace */
+       } else {
+               process->execution_stack =
+                 g_array_set_size(process->execution_stack, 2);
+               es = process->state = &g_array_index(process->execution_stack, 
+                 LttvExecutionState, 1);
+               es->t = LTTV_STATE_SYSCALL;
+               es->n = LTTV_STATE_SUBMODE_NONE;
+               es->entry = *timestamp;
+               //g_assert(timestamp->tv_sec != 0);
+               es->change = *timestamp;
+               es->cum_cpu_time = ltt_time_zero;
+               if(es->s == LTTV_STATE_WAIT_FORK)
+                 es->s = LTTV_STATE_WAIT;
+       }
       }
     }
   }
@@ -3636,6 +3694,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self)
          LTT_FIELD_PREV_STATE),
         schedchange, NULL, &hooks);
 
+    lttv_trace_find_hook(ts->parent.t,
+       LTT_CHANNEL_KERNEL,
+       LTT_EVENT_SCHED_TRY_WAKEUP,              
+       FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_CPU_ID, LTT_FIELD_STATE),
+       sched_try_wakeup, NULL, &hooks);
+
     lttv_trace_find_hook(ts->parent.t,
         LTT_CHANNEL_KERNEL,
         LTT_EVENT_PROCESS_FORK,
@@ -4482,6 +4546,8 @@ static void module_init()
   LTT_FIELD_SYMBOL        = g_quark_from_string("symbol");
   LTT_FIELD_IP            = g_quark_from_string("ip");
   LTT_FIELD_FD            = g_quark_from_string("fd");
+  LTT_FIELD_STATE         = g_quark_from_string("state");
+  LTT_FIELD_CPU_ID        = g_quark_from_string("cpu_id");
   
   LTTV_CPU_UNKNOWN = g_quark_from_string("unknown");
   LTTV_CPU_IDLE = g_quark_from_string("idle");
This page took 0.025067 seconds and 4 git commands to generate.