Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ptools/pmap/pmap_common.c
+++ new/usr/src/cmd/ptools/pmap/pmap_common.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26 /*
27 27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 28 */
29 29
30 30 #include <fcntl.h>
31 31 #include <libproc.h>
32 32 #include <limits.h>
33 33 #include <stdio.h>
34 34 #include <strings.h>
35 35 #include <sys/mkdev.h>
36 36 #include <sys/stat.h>
37 37 #include <sys/types.h>
38 38
39 39 #include "pmap_common.h"
40 40 #include "ptools_common.h"
41 41
42 42 /*
43 43 * We compare the high memory addresses since stacks are faulted in from
44 44 * high memory addresses to low memory addresses, and our prmap_t
45 45 * structures identify only the range of addresses that have been faulted
46 46 * in so far.
47 47 */
48 48 int
49 49 cmpstacks(const void *ap, const void *bp)
50 50 {
51 51 const lwpstack_t *as = ap;
52 52 const lwpstack_t *bs = bp;
53 53 uintptr_t a = (uintptr_t)as->lwps_stack.ss_sp + as->lwps_stack.ss_size;
54 54 uintptr_t b = (uintptr_t)bs->lwps_stack.ss_sp + bs->lwps_stack.ss_size;
55 55
56 56 if (a < b)
57 57 return (1);
58 58 if (a > b)
59 59 return (-1);
60 60 return (0);
61 61 }
62 62
63 63 /*
64 64 * Create labels for non-anon, non-heap mappings
65 65 */
66 66 char *
67 67 make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr,
68 68 const char *mapname, char *buf, size_t bufsz)
69 69 {
70 70 const pstatus_t *Psp = Pstatus(Pr);
71 71 struct stat statb;
72 72 char path[PATH_MAX];
73 73 int len;
74 74
75 75 if (lflag || Pstate(Pr) == PS_DEAD) {
76 76 if (Pobjname(Pr, addr, buf, bufsz) != NULL)
77 77 return (buf);
78 78 } else {
79 79 if (Pobjname_resolved(Pr, addr, buf, bufsz) != NULL) {
80 80 /* Verify that the path exists */
81 81 if ((len = resolvepath(buf, buf, bufsz)) > 0) {
82 82 buf[len] = '\0';
83 83 return (buf);
84 84 }
85 85 }
86 86 }
87 87
88 88 if (Pstate(Pr) == PS_DEAD || *mapname == '\0')
89 89 return (NULL);
90 90
91 91 /* first see if we can find a path via /proc */
92 92 (void) proc_snprintf(path, sizeof (path), "/proc/%d/path/%s",
93 93 (int)Psp->pr_pid, mapname);
94 94 len = readlink(path, buf, bufsz - 1);
95 95 if (len >= 0) {
96 96 buf[len] = '\0';
97 97 return (buf);
98 98 }
99 99
100 100 /* fall back to object information reported by /proc */
101 101 (void) proc_snprintf(path, sizeof (path),
102 102 "/proc/%d/object/%s", (int)Psp->pr_pid, mapname);
103 103 if (stat(path, &statb) == 0) {
104 104 dev_t dev = statb.st_dev;
105 105 ino_t ino = statb.st_ino;
106 106 (void) snprintf(buf, bufsz, "dev:%lu,%lu ino:%lu",
107 107 (ulong_t)major(dev), (ulong_t)minor(dev), ino);
108 108 return (buf);
109 109 }
110 110
111 111 return (NULL);
112 112 }
113 113
114 114 /*
115 115 * Create label for anon mappings
116 116 */
117 117 char *
118 118 anon_name(char *name, const pstatus_t *Psp, lwpstack_t *stacks, uint_t nstacks,
119 119 uintptr_t vaddr, size_t size, int mflags, int shmid, int *mtypesp)
120 120 {
121 121 int mtypes = 0;
122 122
123 123 if (mflags & MA_ISM) {
124 124 if (shmid == -1)
125 125 (void) snprintf(name, PATH_MAX, " [ %s shmid=null ]",
126 126 (mflags & MA_NORESERVE) ? "ism" : "dism");
127 127 else
128 128 (void) snprintf(name, PATH_MAX, " [ %s shmid=0x%x ]",
129 129 (mflags & MA_NORESERVE) ? "ism" : "dism", shmid);
130 130 mtypes |= (1 << AT_SHARED);
131 131 } else if (mflags & MA_SHM) {
132 132 if (shmid == -1)
133 133 (void) sprintf(name, " [ shmid=null ]");
134 134 else
135 135 (void) sprintf(name, " [ shmid=0x%x ]", shmid);
136 136 mtypes |= (1 << AT_SHARED);
137 137 } else if (vaddr + size > Psp->pr_stkbase &&
138 138 vaddr < Psp->pr_stkbase + Psp->pr_stksize) {
139 139 (void) strcpy(name, " [ stack ]");
140 140 mtypes |= (1 << AT_STACK);
141 141 } else if ((mflags & MA_ANON) &&
142 142 vaddr + size > Psp->pr_brkbase &&
143 143 vaddr < Psp->pr_brkbase + Psp->pr_brksize) {
144 144 (void) strcpy(name, " [ heap ]");
145 145 mtypes |= (1 << AT_HEAP);
146 146 } else {
147 147 lwpstack_t key, *stk;
148 148
149 149 key.lwps_stack.ss_sp = (void *)vaddr;
150 150 key.lwps_stack.ss_size = size;
151 151 if (nstacks > 0 &&
152 152 (stk = bsearch(&key, stacks, nstacks, sizeof (stacks[0]),
153 153 cmpstacks)) != NULL) {
154 154 (void) snprintf(name, PATH_MAX, " [ %s tid=%d ]",
155 155 (stk->lwps_stack.ss_flags & SS_ONSTACK) ?
156 156 "altstack" : "stack",
157 157 stk->lwps_lwpid);
158 158 mtypes |= (1 << AT_STACK);
159 159 } else {
160 160 (void) strcpy(name, " [ anon ]");
161 161 mtypes |= (1 << AT_PRIVM);
162 162 }
163 163 }
164 164
165 165 if (mtypesp)
166 166 *mtypesp = mtypes;
167 167 return (name);
168 168 }
|
↓ open down ↓ |
168 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX