svn commit: r347943 - head/sys/cddl/dev/dtrace/powerpc
Justin Hibbits
jhibbits at FreeBSD.org
Fri May 17 19:57:10 UTC 2019
Author: jhibbits
Date: Fri May 17 19:57:08 2019
New Revision: 347943
URL: https://svnweb.freebsd.org/changeset/base/347943
Log:
powerpc/dtrace: Actually fix stack traces
Fix stack unwinding such that requesting N stack frames in lockstat will
actually give you N frames, not anywhere from 0-3 as had been before.
lockstat prints the mutex function instead of the caller as the reported
locker, but the stack frame is detailed enough to find the real caller.
MFC after: 2 weeks
Modified:
head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S Fri May 17 19:27:07 2019 (r347942)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S Fri May 17 19:57:08 2019 (r347943)
@@ -179,3 +179,13 @@ ASENTRY_NOPROF(dtrace_caller)
li %r3, -1
blr
END(dtrace_caller)
+
+/*
+greg_t
+dtrace_getfp(void)
+*/
+ASENTRY_NOPROF(dtrace_getfp)
+ mr %r3,%r31
+ blr
+END(dtrace_getfp)
+
Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c Fri May 17 19:27:07 2019 (r347942)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c Fri May 17 19:57:08 2019 (r347943)
@@ -61,8 +61,10 @@
#define FRAME_OFFSET 8
#endif
-#define INKERNEL(x) ((x) <= VM_MAX_KERNEL_ADDRESS && \
- (x) >= VM_MIN_KERNEL_ADDRESS)
+#define INKERNEL(x) (((x) <= VM_MAX_KERNEL_ADDRESS && \
+ (x) >= VM_MIN_KERNEL_ADDRESS) || \
+ (PMAP_HAS_DMAP && (x) >= DMAP_BASE_ADDRESS && \
+ (x) <= DMAP_MAX_ADDRESS))
static __inline int
dtrace_sp_inkernel(uintptr_t sp)
@@ -70,6 +72,9 @@ dtrace_sp_inkernel(uintptr_t sp)
struct trapframe *frame;
vm_offset_t callpc;
+ /* Not within the kernel, or not aligned. */
+ if (!INKERNEL(sp) || (sp & 0xf) != 0)
+ return (0);
#ifdef __powerpc64__
callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
#else
@@ -84,8 +89,6 @@ dtrace_sp_inkernel(uintptr_t sp)
*/
if (callpc + OFFSET == (vm_offset_t) &trapexit ||
callpc + OFFSET == (vm_offset_t) &asttrapexit) {
- if (sp == 0)
- return (0);
frame = (struct trapframe *)(sp + FRAME_OFFSET);
return ((frame->srr1 & PSL_PR) == 0);
@@ -119,6 +122,7 @@ dtrace_next_sp_pc(uintptr_t sp, uintptr_t *nsp, uintpt
*nsp = frame->fixreg[1];
if (pc != NULL)
*pc = frame->srr0;
+ return;
}
if (nsp != NULL)
@@ -127,12 +131,6 @@ dtrace_next_sp_pc(uintptr_t sp, uintptr_t *nsp, uintpt
*pc = callpc;
}
-greg_t
-dtrace_getfp(void)
-{
- return (greg_t)__builtin_frame_address(0);
-}
-
void
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
uint32_t *intrpc)
@@ -148,7 +146,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in
aframes++;
- sp = dtrace_getfp();
+ sp = (uintptr_t)__builtin_frame_address(0);
while (depth < pcstack_limit) {
if (sp <= osp)
@@ -418,7 +416,7 @@ uint64_t
dtrace_getarg(int arg, int aframes)
{
uintptr_t val;
- uintptr_t *fp = (uintptr_t *)dtrace_getfp();
+ uintptr_t *fp = (uintptr_t *)__builtin_frame_address(0);
uintptr_t *stack;
int i;
@@ -432,8 +430,8 @@ dtrace_getarg(int arg, int aframes)
fp = (uintptr_t *)*fp;
/*
- * On ppc32 AIM, and booke, trapexit() is the immediately following
- * label. On ppc64 AIM trapexit() follows a nop.
+ * On ppc32 trapexit() is the immediately following label. On
+ * ppc64 AIM trapexit() follows a nop.
*/
#ifdef __powerpc64__
if ((long)(fp[2]) + 4 == (long)trapexit) {
@@ -506,9 +504,7 @@ dtrace_getstackdepth(int aframes)
vm_offset_t callpc;
osp = PAGE_SIZE;
- aframes++;
- sp = dtrace_getfp();
- depth++;
+ sp = (uintptr_t)__builtin_frame_address(0);
for(;;) {
if (sp <= osp)
break;
@@ -516,17 +512,14 @@ dtrace_getstackdepth(int aframes)
if (!dtrace_sp_inkernel(sp))
break;
- if (aframes == 0)
- depth++;
- else
- aframes--;
+ depth++;
osp = sp;
dtrace_next_sp_pc(sp, &sp, NULL);
}
if (depth < aframes)
return (0);
- return (depth);
+ return (depth - aframes);
}
ulong_t
More information about the svn-src-all
mailing list