Add functions to open trace from the traceset
[lttv.git] / lttv / lttv / state.c
index bd3f64d6cd08473ece9108b784c4c6add5c815c7..f3c4bb7d16a76f2d2ce8d09a624ec431dda26f93 100644 (file)
@@ -20,7 +20,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-
 #include <glib.h>
 #include <lttv/lttv.h>
 #include <lttv/module.h>
@@ -143,8 +143,11 @@ GQuark
 LttvExecutionMode
        LTTV_STATE_MODE_UNKNOWN,
        LTTV_STATE_USER_MODE,
+       LTTV_STATE_MAYBE_USER_MODE,
        LTTV_STATE_SYSCALL,
+       LTTV_STATE_MAYBE_SYSCALL,
        LTTV_STATE_TRAP,
+       LTTV_STATE_MAYBE_TRAP,
        LTTV_STATE_IRQ,
        LTTV_STATE_SOFT_IRQ;
 
@@ -578,6 +581,7 @@ static void state_load_saved_states(LttvTraceState *tcs)
        gint hdr;
        gchar buf[MAX_STRING_LEN];
        guint len;
+       size_t res;
 
        trace_path = g_quark_to_string(ltt_trace_name(tcs->parent.t));
        strncpy(path, trace_path, PATH_MAX-1);
@@ -600,7 +604,8 @@ static void state_load_saved_states(LttvTraceState *tcs)
                g_ptr_array_set_size(quarktable, q+1);
                i=0;
                while(1) {
-                       fread(&buf[i], sizeof(gchar), 1, fp);
+                       res = fread(&buf[i], sizeof(gchar), 1, fp);
+                       g_assert(res == 1);
                        if(buf[i] == '\0' || feof(fp)) break;
                        i++;
                }
@@ -655,6 +660,8 @@ static void init(LttvTracesetState *self, LttvTraceset *ts)
                        init((LttvTracesetContext *)self, ts);
 
        nb_trace = lttv_traceset_number(ts);
+
+#ifdef BABEL_CLEANUP
        for(i = 0 ; i < nb_trace ; i++) {
                tc = self->parent.traces[i];
                tcs = LTTV_TRACE_STATE(tc);
@@ -733,10 +740,12 @@ static void init(LttvTracesetState *self, LttvTraceset *ts)
                /* See if the trace has saved states */
                state_load_saved_states(tcs);
        }
+#endif
 }
 
 static void fini(LttvTracesetState *self)
 {
+#ifdef BABEL_CLEANUP
        guint i, nb_trace;
 
        LttvTraceState *tcs;
@@ -766,6 +775,7 @@ static void fini(LttvTracesetState *self)
                tcs->processes = NULL;
                tcs->usertraces = NULL;
        }
+#endif
        LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
                        fini((LttvTracesetContext *)self);
 }
@@ -1053,20 +1063,21 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp,
        LttvProcessState *process, *parent_process;
        LttvProcessState tmp;
        GQuark tmpq;
+       size_t res;
 
        guint64 *address;
 
-       /* TODO : check return value */
-       fread(&tmp.type, sizeof(tmp.type), 1, fp);
-       fread(&tmp.name, sizeof(tmp.name), 1, fp);
-       fread(&tmp.brand, sizeof(tmp.brand), 1, fp);
-       fread(&tmp.pid, sizeof(tmp.pid), 1, fp);
-       fread(&tmp.free_events, sizeof(tmp.free_events), 1, fp);
-       fread(&tmp.tgid, sizeof(tmp.tgid), 1, fp);
-       fread(&tmp.ppid, sizeof(tmp.ppid), 1, fp);
-       fread(&tmp.cpu, sizeof(tmp.cpu), 1, fp);
-       fread(&tmp.creation_time, sizeof(tmp.creation_time), 1, fp);
-       fread(&tmp.insertion_time, sizeof(tmp.insertion_time), 1, fp);
+       res = fread(&tmp.type, sizeof(tmp.type), 1, fp);
+       res += fread(&tmp.name, sizeof(tmp.name), 1, fp);
+       res += fread(&tmp.brand, sizeof(tmp.brand), 1, fp);
+       res += fread(&tmp.pid, sizeof(tmp.pid), 1, fp);
+       res += fread(&tmp.free_events, sizeof(tmp.free_events), 1, fp);
+       res += fread(&tmp.tgid, sizeof(tmp.tgid), 1, fp);
+       res += fread(&tmp.ppid, sizeof(tmp.ppid), 1, fp);
+       res += fread(&tmp.cpu, sizeof(tmp.cpu), 1, fp);
+       res += fread(&tmp.creation_time, sizeof(tmp.creation_time), 1, fp);
+       res += fread(&tmp.insertion_time, sizeof(tmp.insertion_time), 1, fp);
+       g_assert(res == 10);
 
        if(tmp.pid == 0) {
                process = lttv_state_find_process(self, tmp.cpu, tmp.pid);
@@ -1109,18 +1120,22 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp,
                                                process->execution_stack->len-1);
                                process->state = es;
 
-                               fread(&es->t, sizeof(es->t), 1, fp);
+                               res = fread(&es->t, sizeof(es->t), 1, fp);
+                               g_assert(res == 1);
                                es->t = g_quark_from_string(
                                                (gchar*)g_ptr_array_index(quarktable, es->t));
-                               fread(&es->n, sizeof(es->n), 1, fp);
+                               res = fread(&es->n, sizeof(es->n), 1, fp);
+                               g_assert(res == 1);
                                es->n = g_quark_from_string(
                                                (gchar*)g_ptr_array_index(quarktable, es->n));
-                               fread(&es->s, sizeof(es->s), 1, fp);
+                               res = fread(&es->s, sizeof(es->s), 1, fp);
+                               g_assert(res == 1);
                                es->s = g_quark_from_string(
                                                (gchar*)g_ptr_array_index(quarktable, es->s));
-                               fread(&es->entry, sizeof(es->entry), 1, fp);
-                               fread(&es->change, sizeof(es->change), 1, fp);
-                               fread(&es->cum_cpu_time, sizeof(es->cum_cpu_time), 1, fp);
+                               res = fread(&es->entry, sizeof(es->entry), 1, fp);
+                               res += fread(&es->change, sizeof(es->change), 1, fp);
+                               res += fread(&es->cum_cpu_time, sizeof(es->cum_cpu_time), 1, fp);
+                               g_assert(res == 3);
                                break;
 
                        case HDR_USER_STACK:
@@ -1128,13 +1143,16 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp,
                                                process->user_stack->len + 1);
                                address = &g_array_index(process->user_stack, guint64,
                                                process->user_stack->len-1);
-                               fread(address, sizeof(address), 1, fp);
+                               res = fread(address, sizeof(address), 1, fp);
+                               g_assert(res == 1);
                                process->current_function = *address;
                                break;
 
                        case HDR_USERTRACE:
-                               fread(&tmpq, sizeof(tmpq), 1, fp);
-                               fread(&process->usertrace->cpu, sizeof(process->usertrace->cpu), 1, fp);
+                               res = fread(&tmpq, sizeof(tmpq), 1, fp);
+                               res += fread(&process->usertrace->cpu,
+                                               sizeof(process->usertrace->cpu), 1, fp);
+                               g_assert(res == 2);
                                break;
 
                        default:
@@ -1160,6 +1178,7 @@ void lttv_state_read_raw(LttvTraceState *self, FILE *fp, GPtrArray *quarktable)
        guint nb_cpus;
 
        int hdr;
+       size_t res;
 
        LttTime t;
 
@@ -1171,7 +1190,8 @@ void lttv_state_read_raw(LttvTraceState *self, FILE *fp, GPtrArray *quarktable)
 
        restore_init_state(self);
 
-       fread(&t, sizeof(t), 1, fp);
+       res = fread(&t, sizeof(t), 1, fp);
+       g_assert(res == 1);
 
        do {
                if(feof(fp) || ferror(fp)) goto end_loop;
@@ -1208,10 +1228,12 @@ end_loop:
                int cpu_num;
                hdr = fgetc(fp);
                g_assert(hdr == HDR_CPU);
-               fread(&cpu_num, sizeof(cpu_num), 1, fp); /* cpu number */
+               res = fread(&cpu_num, sizeof(cpu_num), 1, fp); /* cpu number */
+               g_assert(res == 1);
                g_assert(i == cpu_num);
-               fread(&self->running_process[i]->pid,
+               res = fread(&self->running_process[i]->pid,
                                sizeof(self->running_process[i]->pid), 1, fp);
+               g_assert(res == 1);
        }
 
        nb_tracefile = self->parent.tracefiles->len;
@@ -1226,13 +1248,15 @@ end_loop:
                g_tree_remove(pqueue, &tfcs->parent);
                hdr = fgetc(fp);
                g_assert(hdr == HDR_TRACEFILE);
-               fread(&tfcs->parent.timestamp, sizeof(tfcs->parent.timestamp), 1, fp);
+               res = fread(&tfcs->parent.timestamp, sizeof(tfcs->parent.timestamp), 1, fp);
+               g_assert(res == 1);
                /* Note : if timestamp if LTT_TIME_INFINITE, there will be no
                 * position following : end of trace */
                if(ltt_time_compare(tfcs->parent.timestamp, ltt_time_infinite) != 0) {
-                       fread(&nb_block, sizeof(nb_block), 1, fp);
-                       fread(&offset, sizeof(offset), 1, fp);
-                       fread(&tsc, sizeof(tsc), 1, fp);
+                       res = fread(&nb_block, sizeof(nb_block), 1, fp);
+                       res += fread(&offset, sizeof(offset), 1, fp);
+                       res += fread(&tsc, sizeof(tsc), 1, fp);
+                       g_assert(res == 3);
                        ltt_event_position_set(ep, tfcs->parent.tf, nb_block, offset, tsc);
                        gint ret = ltt_tracefile_seek_position(tfcs->parent.tf, ep);
                        g_assert(ret == 0);
@@ -1820,8 +1844,6 @@ static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
 {
        guint i, nb_tracefile, nb_cpus, nb_irqs, nb_soft_irqs;
 
-       LttvTracefileState *tfcs;
-
        LttvAttribute *tracefiles_tree, *tracefile_tree;
 
        guint *running_process;
@@ -1881,9 +1903,7 @@ static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
        nb_tracefile = self->parent.tracefiles->len;
 
        for(i = 0 ; i < nb_tracefile ; i++) {
-               tfcs =
-                               LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
-                                               LttvTracefileContext*, i));
+       
                type = lttv_attribute_get(tracefiles_tree, i, &name, &value, &is_named);
                g_assert(type == LTTV_GOBJECT);
                tracefile_tree = *((LttvAttribute **)(value.v_gobject));
@@ -2001,9 +2021,9 @@ static void create_name_tables(LttvTraceState *tcs)
 //                     }
 //             }
 
-               name_tables->nb_syscalls = 256;
-               name_tables->syscall_names = g_new(GQuark, 256);
-               for(i = 0 ; i < 256 ; i++) {
+               name_tables->nb_syscalls = PREALLOC_NB_SYSCALLS;
+               name_tables->syscall_names = g_new(GQuark, name_tables->nb_syscalls);
+               for(i = 0 ; i < name_tables->nb_syscalls; i++) {
                        g_string_printf(fe_name, "syscall %d", i);
                        name_tables->syscall_names[i] = g_quark_from_string(fe_name->str);
                }
@@ -2035,9 +2055,9 @@ static void create_name_tables(LttvTraceState *tcs)
 //                                     ltt_enum_string_get(t, i));
 //             }
 
-               name_tables->nb_traps = 256;
-               name_tables->trap_names = g_new(GQuark, 256);
-               for(i = 0 ; i < 256 ; i++) {
+               name_tables->nb_traps = PREALLOC_NB_TRAPS;
+               name_tables->trap_names = g_new(GQuark, name_tables->nb_traps);
+               for(i = 0 ; i < name_tables->nb_traps; i++) {
                        g_string_printf(fe_name, "trap %d", i);
                        name_tables->trap_names[i] = g_quark_from_string(fe_name->str);
                }
@@ -2060,11 +2080,10 @@ static void create_name_tables(LttvTraceState *tcs)
                }
                */
                /* FIXME: LttvIRQState *irq_states should become a g_array */
-               /* temp fix: increase from 256 to 512 default size */
 
-               name_tables->nb_irqs = 512;
-               name_tables->irq_names = g_new(GQuark, 512);
-               for(i = 0 ; i < 512 ; i++) {
+               name_tables->nb_irqs = PREALLOC_NB_IRQS;
+               name_tables->irq_names = g_new(GQuark, name_tables->nb_irqs);
+               for(i = 0 ; i < name_tables->nb_irqs; i++) {
                        g_string_printf(fe_name, "irq %d", i);
                        name_tables->irq_names[i] = g_quark_from_string(fe_name->str);
                }
@@ -2080,8 +2099,7 @@ static void create_name_tables(LttvTraceState *tcs)
        }
        */
 
-       /* the kernel is limited to 32 statically defined softirqs */
-       name_tables->nb_soft_irqs = 32;
+       name_tables->nb_soft_irqs = PREALLOC_NB_SOFT_IRQS;
        name_tables->soft_irq_names = g_new(GQuark, name_tables->nb_soft_irqs);
        for(i = 0 ; i < name_tables->nb_soft_irqs ; i++) {
                g_string_printf(fe_name, "softirq %d", i);
@@ -2678,21 +2696,10 @@ static gboolean soft_irq_raise(void *hook_data, void *call_data)
        //guint8 ev_id = ltt_event_eventtype_id(e);
        LttvTraceHook *th = (LttvTraceHook *)hook_data;
        struct marker_field *f = lttv_trace_get_hook_field(th, 0);
-       LttvNameTables *nt = ((LttvTraceState *)(s->parent.t_context))->name_tables;
 
-       LttvExecutionSubmode submode;
        guint64 softirq = ltt_event_get_long_unsigned(e, f);
-       guint64 nb_softirqs = nt->nb_soft_irqs;
 
-       if(softirq < nb_softirqs) {
-               submode = nt->soft_irq_names[softirq];
-       } else {
-               /* Fixup an incomplete irq table */
-               GString *string = g_string_new("");
-               g_string_printf(string, "softirq %" PRIu64, softirq);
-               submode = g_quark_from_string(string->str);
-               g_string_free(string, TRUE);
-       }
+       expand_soft_irq_table(ts, softirq);
 
        /* update softirq status */
        /* a soft irq raises are not cumulative */
@@ -2887,11 +2894,9 @@ static gboolean dump_syscall(void *hook_data, void *call_data)
        LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
        LttvTraceHook *th = (LttvTraceHook *)hook_data;
        guint id;
-       guint64 address;
        char *symbol;
 
        id = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 0));
-       address = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 1));
        symbol = ltt_event_get_string(e, lttv_trace_get_hook_field(th, 2));
 
        expand_syscall_table(ts, id);
@@ -2925,11 +2930,9 @@ static gboolean dump_softirq(void *hook_data, void *call_data)
        LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
        LttvTraceHook *th = (LttvTraceHook *)hook_data;
        guint id;
-       guint64 address;
        char *symbol;
 
        id = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 0));
-       address = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 1));
        symbol = ltt_event_get_string(e, lttv_trace_get_hook_field(th, 2));
 
        expand_soft_irq_table(ts, id);
@@ -2954,8 +2957,12 @@ static gboolean sched_try_wakeup(void *hook_data, void *call_data)
                        (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;
+
+       if (process->state->s == LTTV_STATE_WAIT || process->state->s == LTTV_STATE_WAIT_FORK)
+       {
+               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);
 
@@ -2996,8 +3003,11 @@ static gboolean schedchange(void *hook_data, void *call_data)
                if(process->pid == 0
                        && process->state->t == LTTV_STATE_MODE_UNKNOWN) {
                        if(pid_out == 0) {
-                               /* Scheduling out of pid 0 at beginning of the trace :
-                                * we know for sure it is in syscall mode at this point. */
+                               /*
+                                * Scheduling out of pid 0 at beginning of the trace.
+                                * We are typically in system call mode at this point although
+                                * (FIXME) we might be in a trap handler.
+                                */
                                g_assert(process->execution_stack->len == 1);
                                process->state->t = LTTV_STATE_SYSCALL;
                                process->state->s = LTTV_STATE_WAIT;
@@ -3057,7 +3067,6 @@ static gboolean process_fork(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;
-       guint parent_pid;
        guint child_pid;   /* In the Linux Kernel, there is one PID per thread. */
        guint child_tgid;  /* tgid in the Linux kernel is the "real" POSIX PID. */
        //LttvProcessState *zombie_process;
@@ -3067,8 +3076,7 @@ static gboolean process_fork(void *hook_data, void *call_data)
        LttvProcessState *child_process;
        struct marker_field *f;
 
-       /* Parent PID */
-       parent_pid = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 0));
+       /* Skip Parent PID param */
 
        /* Child PID */
        child_pid = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 1));
@@ -3343,7 +3351,7 @@ static void fix_process(gpointer key, gpointer value, gpointer user_data)
 
        if(process->type == LTTV_STATE_KERNEL_THREAD) {
                es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
-               if(es->t == LTTV_STATE_MODE_UNKNOWN) {
+               if(es->t == LTTV_STATE_MAYBE_SYSCALL) {
                        es->t = LTTV_STATE_SYSCALL;
                        es->n = LTTV_STATE_SUBMODE_NONE;
                        es->entry = *timestamp;
@@ -3354,7 +3362,7 @@ static void fix_process(gpointer key, gpointer value, gpointer user_data)
                }
        } else {
                es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
-               if(es->t == LTTV_STATE_MODE_UNKNOWN) {
+               if(es->t == LTTV_STATE_MAYBE_USER_MODE) {
                        es->t = LTTV_STATE_USER_MODE;
                        es->n = LTTV_STATE_SUBMODE_NONE;
                        es->entry = *timestamp;
@@ -3424,7 +3432,7 @@ static gboolean enum_process_state(void *hook_data, void *call_data)
        LttvProcessState *process = ts->running_process[cpu];
        LttvProcessState *parent_process;
        struct marker_field *f;
-       GQuark type, mode, submode, status;
+       GQuark type;
        LttvExecutionState *es;
        guint i, nb_cpus;
 
@@ -3444,17 +3452,11 @@ static gboolean enum_process_state(void *hook_data, void *call_data)
 
        //FIXME: type is rarely used, enum must match possible types.
 
-       /* mode */
-       f = lttv_trace_get_hook_field(th, 4);
-       mode = ltt_enum_string_get(f,ltt_event_get_unsigned(e, f));
+       /* Skip mode 4th param */
 
-       /* submode */
-       f = lttv_trace_get_hook_field(th, 5);
-       submode = ltt_enum_string_get(f, ltt_event_get_unsigned(e, f));
+       /* Skip submode 5th param */
 
-       /* status */
-       f = lttv_trace_get_hook_field(th, 6);
-       status = ltt_enum_string_get(f, ltt_event_get_unsigned(e, f));
+       /* Skip status 6th param */
 
        /* TGID */
        f = lttv_trace_get_hook_field(th, 7);
@@ -3500,14 +3502,11 @@ static gboolean enum_process_state(void *hook_data, void *call_data)
                                es = process->state = &g_array_index(process->execution_stack,
                                                LttvExecutionState, 0);
                                process->type = LTTV_STATE_KERNEL_THREAD;
-                               es->t = LTTV_STATE_MODE_UNKNOWN;
+                               es->t = LTTV_STATE_MAYBE_SYSCALL;
                                es->s = LTTV_STATE_UNNAMED;
                                es->n = LTTV_STATE_SUBMODE_UNKNOWN;
-#if 0
-                               es->t = LTTV_STATE_SYSCALL;
-                               es->s = status;
-                               es->n = submode;
-#endif //0
+                               //es->s = status;
+                               //es->n = submode;
                        } else {
                                /* User space process :
                                 * bottom : user mode
@@ -3525,14 +3524,11 @@ static gboolean enum_process_state(void *hook_data, void *call_data)
                                process->execution_stack = g_array_set_size(process->execution_stack, 1);
                                es = process->state = &g_array_index(process->execution_stack,
                                                LttvExecutionState, 0);
-                               es->t = LTTV_STATE_MODE_UNKNOWN;
+                               es->t = LTTV_STATE_MAYBE_USER_MODE;
                                es->s = LTTV_STATE_UNNAMED;
                                es->n = LTTV_STATE_SUBMODE_UNKNOWN;
-       #if 0
-                               es->t = LTTV_STATE_USER_MODE;
-                               es->s = status;
-                               es->n = submode;
-       #endif //0
+                               //es->s = status;
+                               //es->n = submode;
                        }
        #if 0
                        /* UNKNOWN STATE */
@@ -4416,8 +4412,11 @@ static void module_init()
        LTTV_STATE_UNBRANDED = g_quark_from_string("");
        LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("MODE_UNKNOWN");
        LTTV_STATE_USER_MODE = g_quark_from_string("USER_MODE");
+       LTTV_STATE_MAYBE_USER_MODE = g_quark_from_string("MAYBE_USER_MODE");
        LTTV_STATE_SYSCALL = g_quark_from_string("SYSCALL");
+       LTTV_STATE_MAYBE_SYSCALL = g_quark_from_string("MAYBE_SYSCALL");
        LTTV_STATE_TRAP = g_quark_from_string("TRAP");
+       LTTV_STATE_MAYBE_TRAP = g_quark_from_string("MAYBE_TRAP");
        LTTV_STATE_IRQ = g_quark_from_string("IRQ");
        LTTV_STATE_SOFT_IRQ = g_quark_from_string("SOFTIRQ");
        LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("UNKNOWN");
This page took 0.032554 seconds and 4 git commands to generate.