Mercurial > illumos > illumos-gate
diff usr/src/cmd/sgs/librtld_db/demo/common/callstack.c @ 12939:a27c46eb192b
6972234 sgs demo's could use some cleanup
author | Rod Evans <Rod.Evans@Sun.COM> |
---|---|
date | Tue, 27 Jul 2010 22:49:34 -0700 |
parents | usr/src/cmd/sgs/librtld_db/rdb_demo/common/callstack.c@79e3159504fa |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/sgs/librtld_db/demo/common/callstack.c Tue Jul 27 22:49:34 2010 -0700 @@ -0,0 +1,110 @@ +/* + * 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 (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/reg.h> +#include <sys/frame.h> +#include <sys/stack.h> +#include <sys/machelf.h> +#include <procfs.h> + +#include "rdb.h" + +#ifndef STACK_BIAS +#define STACK_BIAS 0 +#endif + +static int +get_frame(struct ps_prochandle *ph, psaddr_t fp, struct frame *frm) +{ +#if defined(_LP64) + /* + * Use special structures to read a 32-bit process + * from a 64-bit process. + */ + if (ph->pp_dmodel == PR_MODEL_ILP32) { + struct frame32 frm32; + + if (ps_pread(ph, (psaddr_t)fp, (char *)&frm32, + sizeof (struct frame32)) != PS_OK) { + (void) printf("stack trace: bad frame pointer: 0x%lx\n", + fp); + return (-1); + } + + frm->fr_savpc = (long)frm32.fr_savpc; +#if defined(__sparcv9) + frm->fr_savfp = (struct frame *)(uintptr_t)frm32.fr_savfp; +#elif defined(__amd64) + frm->fr_savfp = (long)frm32.fr_savfp; +#endif + return (0); + } +#endif /* defined(_LP64) */ + + if (ps_pread(ph, (psaddr_t)fp + STACK_BIAS, (char *)frm, + sizeof (struct frame)) != PS_OK) { + (void) printf("stack trace: bad frame pointer: 0x%lx\n", fp); + return (-1); + } + return (0); +} + +/* + * Relatively architecture neutral routine to display the callstack. + */ +void +CallStack(struct ps_prochandle *ph) +{ + pstatus_t pstatus; + greg_t fp; + struct frame frm; + char *symstr; + + if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1) + perr("cs: reading status"); + + symstr = print_address_ps(ph, (ulong_t)pstatus.pr_lwp.pr_reg[R_PC], + FLG_PAP_SONAME); + (void) printf(" 0x%08x:%-17s\n", EC_WORD(pstatus.pr_lwp.pr_reg[R_PC]), + symstr); + + fp = pstatus.pr_lwp.pr_reg[R_FP]; + + while (fp) { + if (get_frame(ph, (psaddr_t)fp, &frm) == -1) + return; + if (frm.fr_savpc) { + symstr = print_address_ps(ph, (ulong_t)frm.fr_savpc, + FLG_PAP_SONAME); + (void) printf(" 0x%08x:%-17s\n", EC_WORD(frm.fr_savpc), + symstr); + } + fp = (greg_t)frm.fr_savfp; + } +}