#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
#include <glib.h>
#include <lttv/lttv.h>
#include <lttv/module.h>
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;
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);
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++;
}
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);
/* 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;
tcs->processes = NULL;
tcs->usertraces = NULL;
}
+#endif
LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
fini((LttvTracesetContext *)self);
}
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);
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:
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:
guint nb_cpus;
int hdr;
+ size_t res;
LttTime t;
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;
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;
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);
{
guint i, nb_tracefile, nb_cpus, nb_irqs, nb_soft_irqs;
- LttvTracefileState *tfcs;
-
LttvAttribute *tracefiles_tree, *tracefile_tree;
guint *running_process;
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));
// }
// }
- 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);
}
// 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);
}
}
*/
/* 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);
}
}
*/
- /* 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);
//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 */
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);
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);
(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);
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;
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;
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));
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;
}
} 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;
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;
//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);
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
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 */
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");