aboutsummaryrefslogtreecommitdiffstats
path: root/zfs/lib/libumem/getpcstack.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2008-12-10 12:43:20 -0800
committerBrian Behlendorf <[email protected]>2008-12-10 12:43:20 -0800
commit9e8b1e836caa454586797f771a7ad1817ebae315 (patch)
treeb1c55866d36261cf6ed59d6668e14fe079b4cc1e /zfs/lib/libumem/getpcstack.c
parent5e97ed8493584c0d331592894de401edd89f5bab (diff)
Remove libumem, we will try and remove this dependency entirely. If we can't then the best move will simply be to use the official library, or build it as a convenience library
Diffstat (limited to 'zfs/lib/libumem/getpcstack.c')
-rw-r--r--zfs/lib/libumem/getpcstack.c188
1 files changed, 0 insertions, 188 deletions
diff --git a/zfs/lib/libumem/getpcstack.c b/zfs/lib/libumem/getpcstack.c
deleted file mode 100644
index 8c3a47e19..000000000
--- a/zfs/lib/libumem/getpcstack.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "misc.h"
-#include <ucontext.h>
-#include <sys/frame.h>
-#include <sys/stack.h>
-#include <stdio.h>
-
-#if defined(__sparc) || defined(__sparcv9)
-extern void flush_windows(void);
-#define UMEM_FRAMESIZE MINFRAME
-
-#elif defined(__i386) || defined(__amd64)
-/*
- * On x86, MINFRAME is defined to be 0, but we want to be sure we can
- * dereference the entire frame structure.
- */
-#define UMEM_FRAMESIZE (sizeof (struct frame))
-
-#else
-#error needs update for new architecture
-#endif
-
-/*
- * Get a pc-only stacktrace. Used for kmem_alloc() buffer ownership tracking.
- * Returns MIN(current stack depth, pcstack_limit).
- */
-/*ARGSUSED*/
-int
-getpcstack(uintptr_t *pcstack, int pcstack_limit, int check_signal)
-{
- struct frame *fp;
- struct frame *nextfp, *minfp;
- int depth = 0;
- uintptr_t base = 0;
- size_t size = 0;
-#ifndef UMEM_STANDALONE
- int on_altstack = 0;
- uintptr_t sigbase = 0;
- size_t sigsize = 0;
-
- stack_t st;
-
- if (stack_getbounds(&st) != 0) {
- if (thr_stksegment(&st) != 0 ||
- (uintptr_t)st.ss_sp < st.ss_size) {
- return (0); /* unable to get stack bounds */
- }
- /*
- * thr_stksegment(3C) has a slightly different interface than
- * stack_getbounds(3C) -- correct it
- */
- st.ss_sp = (void *)(((uintptr_t)st.ss_sp) - st.ss_size);
- st.ss_flags = 0; /* can't be on-stack */
- }
- on_altstack = (st.ss_flags & SS_ONSTACK);
-
- if (st.ss_size != 0) {
- base = (uintptr_t)st.ss_sp;
- size = st.ss_size;
- } else {
- /*
- * If size == 0, then ss_sp is the *top* of the stack.
- *
- * Since we only allow increasing frame pointers, and we
- * know our caller set his up correctly, we can treat ss_sp
- * as an upper bound safely.
- */
- base = 0;
- size = (uintptr_t)st.ss_sp;
- }
-
- if (check_signal != 0) {
- void (*sigfunc)() = NULL;
- int sigfuncsize = 0;
- extern void thr_sighndlrinfo(void (**)(), int *);
-
- thr_sighndlrinfo(&sigfunc, &sigfuncsize);
- sigbase = (uintptr_t)sigfunc;
- sigsize = sigfuncsize;
- }
-#else /* UMEM_STANDALONE */
- base = (uintptr_t)umem_min_stack;
- size = umem_max_stack - umem_min_stack;
-#endif
-
- /*
- * shorten size so that fr_savfp and fr_savpc will be within the stack
- * bounds.
- */
- if (size >= UMEM_FRAMESIZE - 1)
- size -= (UMEM_FRAMESIZE - 1);
- else
- size = 0;
-
-#if defined(__sparc) || defined(__sparcv9)
- flush_windows();
-#endif
-
- /* LINTED alignment */
- fp = (struct frame *)((caddr_t)getfp() + STACK_BIAS);
-
- minfp = fp;
-
- if (((uintptr_t)fp - base) >= size)
- return (0); /* the frame pointer isn't in our stack */
-
- while (depth < pcstack_limit) {
- uintptr_t tmp;
-
- /* LINTED alignment */
- nextfp = (struct frame *)((caddr_t)fp->fr_savfp + STACK_BIAS);
- tmp = (uintptr_t)nextfp;
-
- /*
- * Check nextfp for validity. It must be properly aligned,
- * increasing compared to the last %fp (or the top of the
- * stack we just switched to), and it must be inside
- * [base, base + size).
- */
- if (tmp != SA(tmp))
- break;
- else if (nextfp <= minfp || (tmp - base) >= size) {
-#ifndef UMEM_STANDALONE
- if (tmp == NULL || !on_altstack)
- break;
- /*
- * If we're on an alternate signal stack, try jumping
- * to the main thread stack.
- *
- * If the main thread stack has an unlimited size, we
- * punt, since we don't know where the frame pointer's
- * been.
- *
- * (thr_stksegment() returns the *top of stack*
- * in ss_sp, not the bottom)
- */
- if (thr_stksegment(&st) == 0) {
- if (st.ss_size >= (uintptr_t)st.ss_sp ||
- st.ss_size < UMEM_FRAMESIZE - 1)
- break;
-
- on_altstack = 0;
- base = (uintptr_t)st.ss_sp - st.ss_size;
- size = st.ss_size - (UMEM_FRAMESIZE - 1);
- minfp = (struct frame *)base;
- continue; /* try again */
- }
-#endif
- break;
- }
-
-#ifndef UMEM_STANDALONE
- if (check_signal && (fp->fr_savpc - sigbase) <= sigsize)
- umem_panic("called from signal handler");
-#endif
- pcstack[depth++] = fp->fr_savpc;
- fp = nextfp;
- minfp = fp;
- }
- return (depth);
-}