PERFORCE change 100506 for review
Howard Su
howardsu at FreeBSD.org
Mon Jul 3 15:13:43 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100506
Change 100506 by howardsu at su_laptop on 2006/07/03 15:13:39
Implement stack() and stackdepth.
Remark: pcpu_find() is used in stack(). So it is not safe to fbt.
Add a comment to fbt.c to keep the record of the dependency.
Affected files ...
.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/i386/dtrace_isa.c#4 edit
.. //depot/projects/dtrace/src/sys/cddl/dev/fbt/fbt.c#4 edit
Differences ...
==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/i386/dtrace_isa.c#4 (text+ko) ====
@@ -23,37 +23,30 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+#include <sys/cdefs.h>
-#if defined(sun)
-#pragma ident "@(#)dtrace_isa.c 1.15 05/09/30 SMI"
-
-#include <sys/dtrace_impl.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/stack.h>
-#include <sys/frame.h>
-#include <sys/cmn_err.h>
-#include <sys/privregs.h>
-#include <sys/sysmacros.h>
+#include <sys/pcpu.h>
-/*
- * This is gross knowledge to have to encode here...
- */
-extern void _interrupt();
-extern void _cmntrap();
-extern void _allsyscalls();
+#include <machine/md_var.h>
-extern size_t _interrupt_size;
-extern size_t _cmntrap_size;
-extern size_t _allsyscalls_size;
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
-extern uintptr_t kernelbase;
-#else
extern uintptr_t kernbase;
uintptr_t kernelbase = (uintptr_t) &kernbase;
+
+#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \
+ ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS)
+
struct frame {
greg_t fr_savfp; /* saved frame pointer */
greg_t fr_savpc; /* saved program counter */
};
-#endif
uint8_t dtrace_fuword8_nocheck(void *);
uint16_t dtrace_fuword16_nocheck(void *);
@@ -64,73 +57,43 @@
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
uint32_t *intrpc)
{
-#ifdef DOODAD
- struct frame *fp = (struct frame *)dtrace_getfp();
- struct frame *nextfp, *minfp, *stacktop;
int depth = 0;
- int on_intr, last = 0;
- uintptr_t pc;
- uintptr_t caller = CPU->cpu_dtrace_caller;
+ vm_offset_t callpc;
+ register_t ebp;
+ struct frame *frame;
+ pc_t caller = (pc_t)pcpu_find(curcpu)->pc_dtrace_caller;
- if ((on_intr = CPU_ON_INTR(CPU)) != 0)
- stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
- else
- stacktop = (struct frame *)curthread->t_stk;
- minfp = fp;
-
+ if (intrpc != 0)
+ pcstack[depth++] = (pc_t)intrpc;
aframes++;
-
- if (intrpc != NULL && depth < pcstack_limit)
- pcstack[depth++] = (pc_t)intrpc;
-
- while (depth < pcstack_limit) {
- nextfp = (struct frame *)fp->fr_savfp;
- pc = fp->fr_savpc;
-
- if (nextfp <= minfp || nextfp >= stacktop) {
- if (on_intr) {
- /*
- * Hop from interrupt stack to thread stack.
- */
- stacktop = (struct frame *)curthread->t_stk;
- minfp = (struct frame *)curthread->t_stkbase;
- on_intr = 0;
- continue;
- }
-
- /*
- * This is the last frame we can process; indicate
- * that we should return after processing this frame.
- */
- last = 1;
- }
-
+ ebp = dtrace_getfp();
+ frame = (struct frame *)ebp;
+ while(depth < pcstack_limit) {
+ if (!INKERNEL(frame))
+ break;
+ callpc = frame->fr_savpc;
+ if (!INKERNEL(callpc))
+ break;
if (aframes > 0) {
- if (--aframes == 0 && caller != NULL) {
- /*
- * We've just run out of artificial frames,
- * and we have a valid caller -- fill it in
- * now.
- */
- ASSERT(depth < pcstack_limit);
- pcstack[depth++] = (pc_t)caller;
- caller = NULL;
+ aframes--;
+ if ((aframes == 0) && (caller != 0)) {
+ pcstack[depth++] = caller;
}
- } else {
- if (depth < pcstack_limit)
- pcstack[depth++] = (pc_t)pc;
}
-
- if (last) {
- while (depth < pcstack_limit)
- pcstack[depth++] = NULL;
- return;
+ else {
+ pcstack[depth++] = callpc;
}
+
+ if ((struct frame *)frame->fr_savfp < frame ||
+ (vm_offset_t)frame->fr_savfp >=
+ (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE)
+ break;
+ frame = (struct frame *)frame->fr_savfp;
+ }
- fp = nextfp;
- minfp = fp;
+ for (; depth < pcstack_limit; depth++) {
+ pcstack[depth] = 0;
}
-#endif
}
static int
@@ -515,49 +478,31 @@
int
dtrace_getstackdepth(int aframes)
{
-#ifdef DOODAD
- struct frame *fp = (struct frame *)dtrace_getfp();
- struct frame *nextfp, *minfp, *stacktop;
int depth = 0;
- int on_intr;
+ struct frame *frame;
+ vm_offset_t ebp;
- if ((on_intr = CPU_ON_INTR(CPU)) != 0)
- stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
- else
- stacktop = (struct frame *)curthread->t_stk;
- minfp = fp;
-
aframes++;
-
- for (;;) {
+ ebp = dtrace_getfp();
+ frame = (struct frame *)ebp;
+ depth++;
+ for(;;) {
+ if (!INKERNEL(frame))
+ break;
+ if (!INKERNEL(frame->fr_savpc))
+ break;
depth++;
-
- nextfp = (struct frame *)fp->fr_savfp;
-
- if (nextfp <= minfp || nextfp >= stacktop) {
- if (on_intr) {
- /*
- * Hop from interrupt stack to thread stack.
- */
- stacktop = (struct frame *)curthread->t_stk;
- minfp = (struct frame *)curthread->t_stkbase;
- on_intr = 0;
- continue;
- }
+ if ((struct frame *)frame->fr_savfp < frame ||
+ (vm_offset_t)frame->fr_savfp >=
+ (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE)
break;
- }
-
- fp = nextfp;
- minfp = fp;
+
+ frame = (struct frame *)frame->fr_savfp;
}
-
- if (depth <= aframes)
- return (0);
-
- return (depth - aframes);
-#else
-return 0;
-#endif
+ if (depth < aframes)
+ return 0;
+ else
+ return depth - aframes;
}
ulong_t
==== //depot/projects/dtrace/src/sys/cddl/dev/fbt/fbt.c#4 (text+ko) ====
@@ -267,7 +267,7 @@
strncmp(name, "linker", 6) == 0 ||
strncmp(name, "witness", 7) == 0 ||
strncmp(name, "spinlock", 8) == 0 ||
- strcmp(name, "pcpu_find") == 0)
+ strcmp(name, "pcpu_find") == 0) /* used in stack() impl */
return (0);
/*
More information about the p4-projects
mailing list