diff mbox series

[QUESTION] arm/perf_callchain.c user stack frame traversal broken on gcc and clang

Message ID CALE8M=49WEOszD4jt+upLD6X0jWtev6==TtdFqjXLRvtrdCrXQ@mail.gmail.com (mailing list archive)
State New, archived
Headers show
Series [QUESTION] arm/perf_callchain.c user stack frame traversal broken on gcc and clang | expand

Commit Message

Igor Katson Sept. 21, 2024, 3:14 p.m. UTC
Hi,

I was debugging why on my ARMv7 router "perf record --call-graph=fp"
didn't produce valid backtraces. --call-graph=dwarf had other issues
that I couldn't resolve yet, so I was trying to make --call-graph=fp
work.

Turned out arch/arm/kernel/perf_callchain.c expects APCS stack frame
layout, which neither modern GCC or clang output with
"-fno-omit-frame-pointer".

GCC has an option "-mapcs-frame" which is deprecated. It seems using
this option is the only way of producing a frame layout that will work
with the mainline kernel.

Here's a tiny patch that made it work on my system. The question is:
does it make sense to try to merge this as an actual patch (I've never
done this before)? There must be a reason it hasn't been fixed yet. I
don't know how bad of a hack this is, so hence asking here and not
submitting as a patch but as a question instead.

  if (tail + 1 >= buftail.fp)
  return NULL;

- return buftail.fp - 1;
+ return buftail.fp;
 }

 void
@@ -75,7 +75,7 @@ perf_callchain_user(struct perf_callchai
  if (!current->mm)
  return;

- tail = (struct frame_tail __user *)regs->ARM_fp - 1;
+ tail = (struct frame_tail __user *)regs->ARM_fp;

  while ((entry->nr < entry->max_stack) &&
        tail && !((unsigned long)tail & 0x3))
diff mbox series

Patch

--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -22,7 +22,7 @@ 
  */
 struct frame_tail {
  struct frame_tail __user *fp;
- unsigned long sp;
  unsigned long lr;
 } __attribute__((packed));

@@ -56,7 +56,7 @@  user_backtrace(struct frame_tail __user