aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/oprofile/backtrace.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-02-24 14:05:47 +1100
committerPaul Mackerras <paulus@samba.org>2006-02-24 14:05:47 +1100
commita00428f5b149e36b8225b2a0812742a6dfb07b8c (patch)
treea78869cd67cf78a0eb091fb0ea5d397734bd6738 /arch/i386/oprofile/backtrace.c
parent774fee58c465ea1c7e9775e347ec307bcf2deeb3 (diff)
parentfb5c594c2acc441f0d2d8f457484a0e0e9285db3 (diff)
downloadlinux-a00428f5b149e36b8225b2a0812742a6dfb07b8c.tar.gz
Merge ../powerpc-merge
Diffstat (limited to 'arch/i386/oprofile/backtrace.c')
-rw-r--r--arch/i386/oprofile/backtrace.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
index acc18138fb2269..c049ce414f0103 100644
--- a/arch/i386/oprofile/backtrace.c
+++ b/arch/i386/oprofile/backtrace.c
@@ -20,7 +20,20 @@ struct frame_head {
} __attribute__((packed));
static struct frame_head *
-dump_backtrace(struct frame_head * head)
+dump_kernel_backtrace(struct frame_head * head)
+{
+ oprofile_add_trace(head->ret);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (head >= head->ebp)
+ return NULL;
+
+ return head->ebp;
+}
+
+static struct frame_head *
+dump_user_backtrace(struct frame_head * head)
{
struct frame_head bufhead[2];
@@ -105,10 +118,10 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
if (!user_mode_vm(regs)) {
while (depth-- && valid_kernel_stack(head, regs))
- head = dump_backtrace(head);
+ head = dump_kernel_backtrace(head);
return;
}
while (depth-- && head)
- head = dump_backtrace(head);
+ head = dump_user_backtrace(head);
}