+2008-03-24 Soren Sandmann <sandmann@daimi.au.dk>
+
+ * collector.c (collect_traces): Call back after collecting all
+ traces.
+
+ * TODO: update
+
+ * process.c: Simpler code to find vmlinux
+
Sat Mar 29 11:14:38 2008 Søren Sandmann <sandmann@redhat.com>
* unwind.[ch], testunwind.c: Beginning of a dwarf unwinder.
- do heuristic stackwalk in kernel
- do heuristic stackwalk in userland
+ - Send heuristic stack trace to user space, along with
+ location on the stack. Then, in userspace analyze the
+ machine code to determine the size of the stack frame at any
+ point. The instructions that would need to be recognized are:
+
+ subl <constant>, %esp
+ addl <constant>, %esp
+ leave
+ jcc
+ push
+ pop
+
+ GCC is unlikely to have different stack sizes at the entry
+ to a basic block.
+
+ We can often find a vmlinux in /lib/modules/<uname-r>/build.
* "Expand all" is horrendously slow because update_screenshot gets called
for every "expanded" signal. In fact even normal expanding is really
static void
collect_traces (Collector *collector)
{
+ gboolean first;
+
/* After a reset we ignore samples for a short period so that
* a reset will actually cause 'samples' to become 0
*/
return;
}
+ first = collector->n_samples == 0;
+
while (collector->current != collector->map_area->head)
{
const SysprofStackTrace *trace;
collector->current = 0;
collector->n_samples++;
-
- if (collector->callback)
- collector->callback (collector->n_samples == 1, collector->data);
}
+
+ if (collector->callback)
+ collector->callback (first, collector->data);
}
static void
static gchar *
look_for_vmlinux (void)
{
+ static const char names[][48] = {
+ "/lib/modules/%s/build/vmlinux",
+ "/usr/lib/debug/lib/modules/%s/vmlinux",
+ "/lib/modules/%s/source/vmlinux",
+ "/boot/vmlinux-%s",
+ };
struct utsname utsname;
- char *result;
- char **s;
- char *names[4];
-
+ int i;
+
uname (&utsname);
- names[0] = g_strdup_printf (
- "/usr/lib/debug/lib/modules/%s/vmlinux", utsname.release);
- names[1] = g_strdup_printf (
- "/lib/modules/%s/source/vmlinux", utsname.release);
- names[2] = g_strdup_printf (
- "/boot/vmlinux-%s", utsname.release);
- names[3] = NULL;
-
- result = NULL;
- for (s = names; *s; s++)
+ for (i = 0; i < G_N_ELEMENTS (names); ++i)
{
- if (file_exists (*s))
- {
- result = g_strdup (*s);
- break;
- }
- }
+ char *filename = g_strdup_printf (names[i], utsname.release);
- for (s = names; *s; s++)
- g_free (*s);
+ if (file_exists (filename))
+ return filename;
- return result;
+ g_free (filename);
+ }
+
+ return NULL;
}
static const gchar *