Date: Mon, 3 Jul 2006 15:13:42 GMT From: Howard Su <howardsu@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 100506 for review Message-ID: <200607031513.k63FDgQk000785@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100506 Change 100506 by howardsu@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); /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607031513.k63FDgQk000785>