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