1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <stdio.h> 27 #include <unistd.h> 28 #include <string.h> 29 #include <sys/types.h> 30 #include <sys/reg.h> 31 #include <sys/frame.h> 32 #include <sys/stack.h> 33 #include <sys/machelf.h> 34 #include <procfs.h> 35 36 #include "rdb.h" 37 38 #ifndef STACK_BIAS 39 #define STACK_BIAS 0 40 #endif 41 42 static int 43 get_frame(struct ps_prochandle *ph, psaddr_t fp, struct frame *frm) 44 { 45 #if defined(_LP64) 46 /* 47 * Use special structures to read a 32-bit process 48 * from a 64-bit process. 49 */ 50 if (ph->pp_dmodel == PR_MODEL_ILP32) { 51 struct frame32 frm32; 52 53 if (ps_pread(ph, (psaddr_t)fp, (char *)&frm32, 54 sizeof (struct frame32)) != PS_OK) { 55 (void) printf("stack trace: bad frame pointer: 0x%lx\n", 56 fp); 57 return (-1); 58 } 59 60 frm->fr_savpc = (long)frm32.fr_savpc; 61 #if defined(__sparcv9) 62 frm->fr_savfp = (struct frame *)(uintptr_t)frm32.fr_savfp; 63 #elif defined(__amd64) 64 frm->fr_savfp = (long)frm32.fr_savfp; 65 #endif 66 return (0); 67 } 68 #endif /* defined(_LP64) */ 69 70 if (ps_pread(ph, (psaddr_t)fp + STACK_BIAS, (char *)frm, 71 sizeof (struct frame)) != PS_OK) { 72 (void) printf("stack trace: bad frame pointer: 0x%lx\n", fp); 73 return (-1); 74 } 75 return (0); 76 } 77 78 /* 79 * Relatively architecture neutral routine to display the callstack. 80 */ 81 void 82 CallStack(struct ps_prochandle *ph) 83 { 84 pstatus_t pstatus; 85 greg_t fp; 86 struct frame frm; 87 char *symstr; 88 89 if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1) 90 perr("cs: reading status"); 91 92 symstr = print_address_ps(ph, (ulong_t)pstatus.pr_lwp.pr_reg[R_PC], 93 FLG_PAP_SONAME); 94 (void) printf(" 0x%08x:%-17s\n", EC_WORD(pstatus.pr_lwp.pr_reg[R_PC]), 95 symstr); 96 97 fp = pstatus.pr_lwp.pr_reg[R_FP]; 98 99 while (fp) { 100 if (get_frame(ph, (psaddr_t)fp, &frm) == -1) 101 return; 102 if (frm.fr_savpc) { 103 symstr = print_address_ps(ph, (ulong_t)frm.fr_savpc, 104 FLG_PAP_SONAME); 105 (void) printf(" 0x%08x:%-17s\n", EC_WORD(frm.fr_savpc), 106 symstr); 107 } 108 fp = (greg_t)frm.fr_savfp; 109 } 110 } 111