sysprof r401 - in trunk: . module
- From: ssp svn gnome org
- To: svn-commits-list gnome org
- Subject: sysprof r401 - in trunk: . module
- Date: Thu, 20 Mar 2008 09:49:47 +0000 (GMT)
Author: ssp
Date: Thu Mar 20 09:49:46 2008
New Revision: 401
URL: http://svn.gnome.org/viewvc/sysprof?rev=401&view=rev
Log:
2008-03-20 Soren Sandmann <sandmann redhat com>
* module/sysprof-module.c (trace_kernel): Use kernel builtin
tracer instead of copying everything ourselves.
Modified:
trunk/ChangeLog
trunk/collector.c
trunk/module/sysprof-module.c
trunk/module/sysprof-module.h
trunk/process.c
Modified: trunk/collector.c
==============================================================================
--- trunk/collector.c (original)
+++ trunk/collector.c Thu Mar 20 09:49:46 2008
@@ -143,8 +143,7 @@
g_assert (a == n_addresses);
#endif
- stack_stash_add_trace (
- stash, addrs, a, 1);
+ stack_stash_add_trace (stash, addrs, a, 1);
if (addrs != addrs_stack)
g_free (addrs);
@@ -195,6 +194,15 @@
g_print ("-=-\n");
}
#endif
+#if 0
+ {
+ int i;
+ g_print ("pid: %d (%d)\n", trace->pid, trace->n_addresses);
+ for (i=0; i < trace->n_kernel_words; ++i)
+ g_print ("rd: %08x\n", trace->kernel_stack[i]);
+ g_print ("-=-\n");
+ }
+#endif
add_trace_to_stash (trace, collector->stash);
@@ -403,7 +411,12 @@
* legitimately be at offset 0.
*/
if (offset == 0 && !first_addr)
+ {
+#if 0
+ g_print ("rejecting callback: %s (%p)\n", sym, address);
+#endif
sym = NULL;
+ }
/* If offset is greater than 4096, then what happened is most
* likely that it is the address of something in the gap between the
@@ -414,7 +427,12 @@
* is, and act accordingly. Actually, we should look at /proc/modules
*/
if (offset > 4096)
+ {
+#if 0
+ g_print ("offset\n");
+#endif
sym = NULL;
+ }
}
else
{
Modified: trunk/module/sysprof-module.c
==============================================================================
--- trunk/module/sysprof-module.c (original)
+++ trunk/module/sysprof-module.c Thu Mar 20 09:49:46 2008
@@ -30,6 +30,7 @@
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
+#include <asm/stacktrace.h>
#include <linux/poll.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
@@ -151,40 +152,84 @@
#endif
}
+/*
+ * The functions backtrace_* are based on oprofile's backtrace.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author David Smith
+ */
+static void backtrace_warning_symbol(void *data, char *msg,
+ unsigned long symbol)
+{
+ /* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+ /* Ignore warnings */
+}
+
+struct backtrace_info_t
+{
+ SysprofStackTrace *trace;
+ int pos;
+};
+
+static int backtrace_stack(void *data, char *name)
+{
+ /* Don't bother with IRQ stacks for now */
+ return -1;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+ struct backtrace_info_t *info = data;
+
+ if (info->pos < SYSPROF_MAX_ADDRESSES && reliable)
+ info->trace->kernel_stack[info->pos++] = (void *)addr;
+}
+
+const static struct stacktrace_ops backtrace_ops = {
+ .warning = backtrace_warning,
+ .warning_symbol = backtrace_warning_symbol,
+ .stack = backtrace_stack,
+ .address = backtrace_address,
+};
+
static struct pt_regs *
-copy_kernel_stack (struct pt_regs *regs,
- SysprofStackTrace *trace)
+trace_kernel (struct pt_regs *regs,
+ SysprofStackTrace *trace)
{
- int n_bytes;
- char *esp;
+ struct backtrace_info_t info;
char *eos;
-
+ unsigned long stack;
+ unsigned long bp;
+
trace->kernel_stack[0] = (void *)regs->REG_INS_PTR;
- trace->n_kernel_words = 1;
- /* The timer interrupt happened in kernel mode. When this
- * happens the registers are pushed on the stack, _except_
- * esp. So we can't use regs->esp to copy the stack pointer.
- * Instead we use the fact that the regs pointer itself
- * points to the stack.
+ info.trace = trace;
+ info.pos = 1;
+
+ stack = (unsigned long) ((char *)regs + sizeof (struct pt_regs));
+#ifdef CONFIG_FRAME_POINTER
+ /* We can't set it to 0, because then the stack trace will
+ * contain the stack of the timer interrupt
*/
- esp = (char *)regs + sizeof (struct pt_regs);
- eos = (char *)current->thread.REG_STACK_PTR0 -
- sizeof (struct pt_regs);
-
- n_bytes = minimum ((char *)eos - esp,
- sizeof (trace->kernel_stack));
-
- if (n_bytes > 0) {
-#if 0
- nt_memcpy (&(trace->kernel_stack[1]), esp, n_bytes);
+ bp = regs->REG_FRAME_PTR;
+#else
+ bp = 0;
#endif
- memcpy (&(trace->kernel_stack[1]), esp, n_bytes);
-
- trace->n_kernel_words += (n_bytes) / sizeof (void *);
- }
+
+ dump_trace(NULL, regs, stack, bp, &backtrace_ops, &info);
+
+ trace->n_kernel_words = info.pos;
/* Now trace the user stack */
+ eos = (char *)current->thread.REG_STACK_PTR0 - sizeof (struct pt_regs);
+
return (struct pt_regs *)eos;
}
@@ -318,7 +363,7 @@
trace->n_addresses = 0;
if (!is_user)
- regs = copy_kernel_stack (regs, trace);
+ regs = trace_kernel (regs, trace);
trace->addresses[0] = (void *)regs->REG_INS_PTR;
trace->n_addresses = 1;
Modified: trunk/module/sysprof-module.h
==============================================================================
--- trunk/module/sysprof-module.h (original)
+++ trunk/module/sysprof-module.h Thu Mar 20 09:49:46 2008
@@ -25,11 +25,11 @@
typedef struct SysprofMmapArea SysprofMmapArea;
#define SYSPROF_N_TRACES 64
-#define SYSPROF_MAX_ADDRESSES 1020 /* to make it three pages wide */
+#define SYSPROF_MAX_ADDRESSES 126
struct SysprofStackTrace
{
- void *kernel_stack[1024];
+ void *kernel_stack[SYSPROF_MAX_ADDRESSES];
void *addresses[SYSPROF_MAX_ADDRESSES];
int n_kernel_words;
int n_addresses; /* note: this can be 1 if the process was compiled
Modified: trunk/process.c
==============================================================================
--- trunk/process.c (original)
+++ trunk/process.c Thu Mar 20 09:49:46 2008
@@ -662,6 +662,14 @@
GArray *ksyms = get_kernel_symbols ();
KernelSymbol *result;
+ if (offset)
+ {
+ /* If we don't have any offset, just return 1, so it doesn't
+ * look like a callback
+ */
+ *offset = 1;
+ }
+
if (ksyms->len == 0)
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]