Print this page
27908 ::gcore breaks sparc build
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/modules/genunix/gcore.c
+++ new/usr/src/cmd/mdb/common/modules/genunix/gcore.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11 /*
12 12 * Copyright (c) 2013 by Delphix. All rights reserved.
13 13 */
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14
15 15 /*
16 16 * This file implements the mdb ::gcore command. The command relies on the
17 17 * libproc Pgcore function to actually generate the core file but we provide
18 18 * our own ops vector to populate data required by Pgcore. The ops vector
19 19 * function implementations simulate the functionality implemented by procfs.
20 20 * The data provided by some of the ops vector functions is not complete
21 21 * (missing data is documented in function headers) but there is enough
22 22 * information to generate a core file that can be loaded into mdb.
23 23 *
24 - * Currently only x86 is supported!
24 + * Currently only x86 is supported. ISA-dependent functions are implemented
25 + * in gcore_isadep.c.
25 26 */
26 27
27 28 #ifndef _KMDB
28 29
29 30 /*
30 31 * The kernel has its own definition of exit which has a different signature
31 32 * than the user space definition. This seems to be the standard way to deal
32 33 * with this.
33 34 */
34 35 #define exit kern_exit
35 36
36 37 #include <mdb/mdb_modapi.h>
37 38 #include <mdb/mdb_param.h>
38 39 #include <mdb/mdb_ks.h>
39 40 #include <mdb/mdb_ctf.h>
40 41 #include <mdb/mdb_debug.h>
42 +#include <mdb/mdb_gcore.h>
41 43
42 44 #include <sys/class.h>
43 45 #include <sys/cpuvar.h>
44 46 #include <sys/proc.h>
45 -#include <sys/cred_impl.h>
46 47 #include <sys/lgrp.h>
47 48 #include <sys/pool.h>
48 49 #include <sys/project.h>
49 50 #include <sys/regset.h>
50 51 #include <sys/schedctl.h>
51 52 #include <sys/session.h>
52 53 #include <sys/syscall.h>
53 54 #include <sys/task.h>
54 55 #include <sys/var.h>
55 56 #include <sys/privregs.h>
56 -#include <sys/psw.h>
57 57 #include <sys/fault.h>
58 -#include <sys/procfs.h>
59 58 #include <sys/sysmacros.h>
60 59 #include <sys/wait.h>
61 60 #include <vm/seg.h>
62 61 #include <vm/vpage.h>
63 62 #include <fs/proc/prdata.h>
64 63
65 64 #undef exit
66 65
67 66 #include <stdio.h>
68 67 #include <stdbool.h>
69 68 #include <string.h>
70 69 #include <libproc.h>
71 70
72 71 #include "avl.h"
73 72
74 73 #ifdef _LP64
75 74 #define LSPAN(type) (P2ROUNDUP(sizeof (type), 16))
76 75 #else
77 76 #define LSPAN(type) (P2ROUNDUP(sizeof (type), 8))
78 77 #endif
79 78
80 79 #define vpgtob(n) ((n) * sizeof (struct vpage))
81 80
82 81 /* Macros to invoke gcore seg operations */
83 82 #define GSOP_INIT(_gs) (_gs)->gs_ops->gsop_init((_gs))
84 83 #define GSOP_FINI(_gs) (_gs)->gs_ops->gsop_fini((_gs))
85 84 #define GSOP_INCORE(_gs, _addr, _eaddr) \
86 85 (_gs)->gs_ops->gsop_incore((_gs), (_addr), (_eaddr))
87 86 #define GSOP_GETPROT(_gs, _addr) \
88 87 (_gs)->gs_ops->gsop_getprot((_gs), (_addr))
89 88 #define GSOP_GETOFFSET(_gs, _addr) \
90 89 (_gs)->gs_ops->gsop_getoffset((_gs), (_addr))
91 90 #define GSOP_GETTYPE(_gs, _addr) \
92 91 (_gs)->gs_ops->gsop_gettype((_gs), (_addr))
93 92 #define GSOP_NAME(_gs, _name, _size) \
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
94 93 (_gs)->gs_ops->gsop_name((_gs), (_name), (_size))
95 94 #define GSOP_NORESERVE(_gs) \
96 95 (_gs)->gs_ops->gsop_noreserve((_gs))
97 96
98 97 #ifdef GCORE_DEBUG
99 98 #define dprintf(...) mdb_printf(__VA_ARGS__)
100 99 #else
101 100 #define dprintf(...)
102 101 #endif
103 102
104 -/* mdb versions of kernel structures used for ctf read calls */
105 -typedef struct mdb_proc {
106 - uintptr_t p_as;
107 - uintptr_t p_brkbase;
108 - size_t p_brksize;
109 - uintptr_t p_usrstack;
110 - size_t p_stksize;
111 - user_t p_user;
112 - uintptr_t p_agenttp;
113 - uintptr_t p_tlist;
114 - uintptr_t p_zone;
115 - uintptr_t p_ldt;
116 - kcondvar_t p_holdlwps;
117 - int p_lwpcnt;
118 - uintptr_t p_lwpdir;
119 - uint_t p_lwpdir_sz;
120 - uintptr_t p_cred;
121 - uint_t p_flag;
122 - int p_zombcnt;
123 - uintptr_t p_pidp;
124 - pid_t p_ppid;
125 - uintptr_t p_pgidp;
126 - uintptr_t p_sessp;
127 - uintptr_t p_task;
128 - uintptr_t p_pool;
129 - model_t p_model;
130 - char p_wcode;
131 - ushort_t p_ldtlimit;
132 - uintptr_t p_exec;
133 - uint_t p_proc_flag;
134 - ushort_t p_pidflag;
135 - k_sigset_t p_ignore;
136 - k_sigset_t p_siginfo;
137 - k_sigset_t p_sig;
138 - k_sigset_t p_sigmask;
139 - k_fltset_t p_fltmask;
140 - int p_wdata;
141 -} mdb_proc_t;
142 -
143 -typedef struct mdb_kthread {
144 - ushort_t t_proc_flag;
145 - uint_t t_state;
146 - lwpchan_t t_lwpchan;
147 - ushort_t t_whystop;
148 - uint8_t t_dtrace_stop;
149 - uintptr_t t_forw;
150 - uintptr_t t_lwp;
151 - id_t t_tid;
152 - short t_sysnum;
153 - pri_t t_pri;
154 - time_t t_start;
155 - id_t t_cid;
156 - uintptr_t t_cpu;
157 - int t_bind_pset;
158 - short t_bind_cpu;
159 - uintptr_t t_lpl;
160 - ushort_t t_schedflag;
161 - ushort_t t_whatstop;
162 - k_sigset_t t_sig;
163 - uintptr_t t_schedctl;
164 - k_sigset_t t_hold;
165 - hrtime_t t_stoptime;
166 -} mdb_kthread_t;
167 -
168 -typedef struct mdb_seg {
169 - uintptr_t s_base;
170 - size_t s_size;
171 - uintptr_t s_ops;
172 - uintptr_t s_data;
173 - uintptr_t s_as;
174 -} mdb_seg_t;
175 -
176 -typedef struct mdb_as {
177 - uintptr_t a_proc;
178 -} mdb_as_t;
179 -
180 -typedef struct mdb_segvn_data {
181 - uintptr_t vp;
182 - uint64_t offset;
183 - uint16_t flags;
184 - uint8_t pageprot;
185 - uint8_t prot;
186 - uintptr_t amp;
187 - struct vpage *vpage;
188 - uint64_t anon_index;
189 - uint8_t type;
190 -} mdb_segvn_data_t;
191 -
192 -typedef struct mdb_vnode {
193 - enum vtype v_type;
194 - uintptr_t v_data;
195 - uintptr_t v_op;
196 - uintptr_t v_path;
197 -} mdb_vnode_t;
198 -
199 -typedef struct mdb_znode {
200 - uint64_t z_size;
201 -} mdb_znode_t;
202 -
203 -typedef struct mdb_tmpnode {
204 - vattr_t tn_attr;
205 -} mdb_tmpnode_t;
206 -
207 -typedef struct mdb_vnodeops {
208 - uintptr_t vnop_name;
209 -} mdb_vnodeops_t;
210 -
211 -typedef struct mdb_shm_data {
212 - uintptr_t shm_sptseg;
213 -} mdb_shm_data_t;
214 -
215 -typedef struct mdb_watched_page {
216 - uintptr_t wp_vaddr;
217 - uint8_t wp_oprot;
218 -} mdb_watched_page_t;
219 -
220 -typedef struct mdb_pid {
221 - pid_t pid_id;
222 -} mdb_pid_t;
223 -
224 -typedef struct mdb_sess {
225 - uintptr_t s_sidp;
226 -} mdb_sess_t;
227 -
228 -typedef struct mdb_task {
229 - taskid_t tk_tkid;
230 - uintptr_t tk_proj;
231 -} mdb_task_t;
232 -
233 -typedef struct mdb_kproject {
234 - projid_t kpj_id;
235 -} mdb_kproject_t;
236 -
237 -typedef struct mdb_zone {
238 - zoneid_t zone_id;
239 - uintptr_t zone_name;
240 -} mdb_zone_t;
241 -
242 -typedef struct mdb_sc_shared {
243 - char sc_sigblock;
244 -} mdb_sc_shared_t;
245 -
246 -typedef struct mdb_klwp {
247 - uintptr_t lwp_regs;
248 - struct pcb lwp_pcb;
249 - uchar_t lwp_asleep;
250 - uchar_t lwp_cursig;
251 - uintptr_t lwp_curinfo;
252 - k_siginfo_t lwp_siginfo;
253 - stack_t lwp_sigaltstack;
254 - uintptr_t lwp_oldcontext;
255 - short lwp_badpriv;
256 - uintptr_t lwp_ustack;
257 - char lwp_eosys;
258 -} mdb_klwp_t;
259 -
260 -typedef struct mdb_cpu {
261 - processorid_t cpu_id;
262 -} mdb_cpu_t;
263 -
264 -typedef struct mdb_lpl {
265 - lgrp_id_t lpl_lgrpid;
266 -} mdb_lpl_t;
267 -
268 -typedef struct mdb_sigqueue {
269 - k_siginfo_t sq_info;
270 -} mdb_sigqueue_t;
271 -
272 -typedef struct mdb_pool {
273 - poolid_t pool_id;
274 -} mdb_pool_t;
275 -
276 -typedef struct mdb_amp {
277 - uintptr_t ahp;
278 -} mdb_amp_t;
279 -
280 -typedef struct mdb_anon_hdr {
281 - pgcnt_t size;
282 - uintptr_t array_chunk;
283 - int flags;
284 -} mdb_anon_hdr_t;
285 -
286 -typedef struct mdb_anon {
287 - uintptr_t an_vp;
288 - anoff_t an_off;
289 -} mdb_anon_t;
290 -
291 -/* Used to construct a linked list of prmap_ts */
292 -typedef struct prmap_node {
293 - struct prmap_node *next;
294 - prmap_t m;
295 -} prmap_node_t;
296 -
297 -/* Fields common to psinfo_t and pstatus_t */
298 -typedef struct pcommon {
299 - int pc_nlwp;
300 - int pc_nzomb;
301 - pid_t pc_pid;
302 - pid_t pc_ppid;
303 - pid_t pc_pgid;
304 - pid_t pc_sid;
305 - taskid_t pc_taskid;
306 - projid_t pc_projid;
307 - zoneid_t pc_zoneid;
308 - char pc_dmodel;
309 -} pcommon_t;
310 -
311 -/* AVL walk callback structures */
312 -typedef struct read_maps_cbarg {
313 - mdb_proc_t *p;
314 - uintptr_t brkseg;
315 - uintptr_t stkseg;
316 - prmap_node_t *map_head;
317 - prmap_node_t *map_tail;
318 - int map_len;
319 -} read_maps_cbarg_t;
320 -
321 -typedef struct as_segat_cbarg {
322 - uintptr_t addr;
323 - uintptr_t res;
324 -} as_segat_cbarg_t;
325 -
326 -typedef struct getwatchprot_cbarg {
327 - uintptr_t wp_vaddr;
328 - mdb_watched_page_t wp;
329 - boolean_t found;
330 -} getwatchprot_cbarg_t;
331 -
332 -struct gcore_segops;
333 -typedef struct gcore_seg {
334 - mdb_seg_t *gs_seg;
335 - void *gs_data;
336 - struct gcore_segops *gs_ops;
337 -} gcore_seg_t;
338 -
339 103 /* Callback function type for processing lwp entries */
340 104 typedef int (*lwp_callback_t)(mdb_proc_t *, lwpent_t *, void *);
341 105
342 106 /* Private data */
343 107 static uintptr_t gcore_segvn_ops;
344 108 static priv_impl_info_t prinfo;
345 109 static sclass_t *gcore_sclass;
346 110 static uintptr_t gcore_kas;
347 111 static boolean_t gcore_initialized = B_FALSE;
348 112
349 113 typedef int (*gsop_init_t)(gcore_seg_t *);
350 114 typedef void (*gsop_fini_t)(gcore_seg_t *);
351 115 typedef u_offset_t (*gsop_incore_t)(gcore_seg_t *, u_offset_t, u_offset_t);
352 116 typedef uint_t (*gsop_getprot_t)(gcore_seg_t *, u_offset_t);
353 117 typedef int (*gsop_getoffset_t)(gcore_seg_t *, u_offset_t);
354 118 typedef void (*gsop_name_t)(gcore_seg_t *, char *name, size_t size);
355 119 typedef int (*gsop_gettype_t)(gcore_seg_t *, u_offset_t);
356 120 typedef boolean_t (*gsop_noreserve_t)(gcore_seg_t *);
357 121
358 122 typedef struct gcore_segops {
359 123 gsop_init_t gsop_init;
360 124 gsop_fini_t gsop_fini;
361 125 gsop_incore_t gsop_incore;
362 126 gsop_getprot_t gsop_getprot;
363 127 gsop_getoffset_t gsop_getoffset;
364 128 gsop_name_t gsop_name;
365 129 gsop_gettype_t gsop_gettype;
366 130 gsop_noreserve_t gsop_noreserve;
367 131 } gcore_segops_t;
368 132
369 133 static void map_list_free(prmap_node_t *);
370 134 static uintptr_t gcore_prchoose(mdb_proc_t *);
371 135
372 136 /*
373 137 * Segvn ops
374 138 */
375 139 static int gsvn_init(gcore_seg_t *);
376 140 static void gsvn_fini(gcore_seg_t *);
377 141 static u_offset_t gsvn_incore(gcore_seg_t *, u_offset_t, u_offset_t);
378 142 static uint_t gsvn_getprot(gcore_seg_t *, u_offset_t);
379 143 static int gsvn_getoffset(gcore_seg_t *, u_offset_t);
380 144 static void gsvn_name(gcore_seg_t *, char *, size_t);
381 145 static int gsvn_gettype(gcore_seg_t *, u_offset_t);
382 146 static boolean_t gsvn_noreserve(gcore_seg_t *);
383 147
384 148 static gcore_segops_t gsvn_ops = {
385 149 .gsop_init = gsvn_init,
386 150 .gsop_fini = gsvn_fini,
387 151 .gsop_incore = gsvn_incore,
388 152 .gsop_getprot = gsvn_getprot,
389 153 .gsop_getoffset = gsvn_getoffset,
390 154 .gsop_name = gsvn_name,
391 155 .gsop_gettype = gsvn_gettype,
392 156 .gsop_noreserve = gsvn_noreserve
393 157 };
394 158
395 159 static int
396 160 gsvn_init(gcore_seg_t *gs)
397 161 {
398 162 mdb_seg_t *seg = gs->gs_seg;
399 163 mdb_segvn_data_t *svd = NULL;
400 164 struct vpage *vpage = NULL;
401 165 size_t nvpage = 0;
402 166
403 167 if (seg->s_data != NULL) {
404 168 svd = mdb_alloc(sizeof (*svd), UM_SLEEP);
405 169 if (mdb_ctf_vread(svd, "segvn_data_t", "mdb_segvn_data_t",
406 170 seg->s_data, 0) == -1) {
407 171 goto error;
408 172 }
409 173
410 174 if (svd->pageprot != 0) {
411 175 nvpage = seg_pages(seg);
412 176 dprintf("vpage count: %d\n", nvpage);
413 177
414 178 vpage = mdb_alloc(vpgtob(nvpage), UM_SLEEP);
415 179 if (mdb_vread(vpage, vpgtob(nvpage),
416 180 (uintptr_t)svd->vpage) != vpgtob(nvpage)) {
417 181 mdb_warn("Failed to read vpages from %p\n",
418 182 svd->vpage);
419 183 goto error;
420 184 }
421 185
422 186 svd->vpage = vpage;
423 187 } else {
424 188 svd->vpage = NULL;
425 189 }
426 190 gs->gs_data = svd;
427 191 } else {
428 192 gs->gs_data = NULL;
429 193 }
430 194
431 195 return (0);
432 196
433 197 error:
434 198 mdb_free(vpage, vpgtob(nvpage));
435 199 mdb_free(svd, sizeof (*svd));
436 200 return (-1);
437 201 }
438 202
439 203 /*ARGSUSED*/
440 204 static int
441 205 gsvn_getoffset(gcore_seg_t *gs, u_offset_t addr)
442 206 {
443 207 mdb_segvn_data_t *svd = gs->gs_data;
444 208 mdb_seg_t *seg = gs->gs_seg;
445 209
446 210 return (svd->offset + (uintptr_t)(addr - seg->s_base));
447 211 }
448 212
449 213 static void
450 214 gsvn_name(gcore_seg_t *gs, char *name, size_t size)
451 215 {
452 216 mdb_segvn_data_t *svd = gs->gs_data;
453 217
454 218 name[0] = '\0';
455 219 if (svd->vp != 0) {
456 220 mdb_seg_t *seg = gs->gs_seg;
457 221 mdb_as_t as;
458 222 mdb_proc_t p;
459 223 mdb_vnode_t vn;
460 224
461 225 if (mdb_ctf_vread(&vn, "vnode_t", "mdb_vnode_t", svd->vp, 0)
462 226 == -1) {
463 227 return;
464 228 }
465 229
466 230 if (mdb_ctf_vread(&as, "struct as", "mdb_as_t", seg->s_as, 0)
467 231 == -1) {
468 232 return;
469 233 }
470 234
471 235 if (mdb_ctf_vread(&p, "proc_t", "mdb_proc_t", as.a_proc, 0)
472 236 == -1) {
473 237 return;
474 238 }
475 239
476 240 if (vn.v_type == VREG && svd->vp == p.p_exec) {
477 241 (void) strncpy(name, "a.out", size);
478 242 }
479 243
480 244 /*
481 245 * procfs has more logic here to construct a name using
482 246 * vfs/vnode identifiers but didn't seem worthwhile to add
483 247 * here.
484 248 */
485 249 }
486 250 }
487 251
488 252 /*ARGSUSED*/
489 253 static int
490 254 gsvn_gettype(gcore_seg_t *gs, u_offset_t addr)
491 255 {
492 256 return (0);
493 257 }
494 258
495 259 static void
496 260 gsvn_fini(gcore_seg_t *gs)
497 261 {
498 262 mdb_segvn_data_t *svd = gs->gs_data;
499 263
500 264 if (svd != NULL) {
501 265 if (svd->vpage != NULL) {
502 266 size_t nvpage = seg_pages(gs->gs_seg);
503 267
504 268 mdb_free(svd->vpage, vpgtob(nvpage));
505 269 }
506 270 mdb_free(svd, sizeof (*svd));
507 271 }
508 272 }
509 273
510 274 static boolean_t
511 275 gsvn_noreserve(gcore_seg_t *gs)
512 276 {
513 277 mdb_segvn_data_t *svd = gs->gs_data;
514 278
515 279 if (svd == NULL) {
516 280 return (B_FALSE);
517 281 }
518 282
519 283 if (svd->flags & MAP_NORESERVE) {
520 284 mdb_vnode_t vn;
521 285
522 286 if (svd->vp == 0) {
523 287 return (B_TRUE);
524 288 }
525 289
526 290 if (mdb_ctf_vread(&vn, "vnode_t", "mdb_vnode_t",
527 291 svd->vp, 0) == -1) {
528 292 return (B_FALSE);
529 293 }
530 294
531 295 if (vn.v_type != VREG) {
532 296 return (B_TRUE);
533 297 }
534 298 }
535 299
536 300 return (B_FALSE);
537 301 }
538 302
539 303 static uintptr_t
540 304 gcore_anon_get_ptr(uintptr_t ah_addr, ulong_t an_idx)
541 305 {
542 306 mdb_anon_hdr_t ah;
543 307 uintptr_t anon_addr;
544 308 uintptr_t anon_ptr;
545 309
546 310 if (mdb_ctf_vread(&ah, "struct anon_hdr", "mdb_anon_hdr_t", ah_addr,
547 311 0) == -1) {
548 312 return (0);
549 313 }
550 314
551 315 /*
552 316 * Single level case.
553 317 */
554 318 if ((ah.size <= ANON_CHUNK_SIZE) || (ah.flags & ANON_ALLOC_FORCE)) {
555 319 anon_addr = ah.array_chunk + (sizeof (anon_ptr) * an_idx);
556 320 if (mdb_vread(&anon_ptr, sizeof (anon_ptr), anon_addr) !=
557 321 sizeof (anon_ptr)) {
558 322 mdb_warn("Failed to read anon_ptr from %p (1 level)\n",
559 323 anon_addr);
560 324 return (0);
561 325 }
562 326
563 327 return (anon_ptr & ANON_PTRMASK);
564 328 }
565 329
566 330 /*
567 331 * 2 level case.
568 332 */
569 333 anon_addr = ah.array_chunk + (sizeof (anon_ptr) *
570 334 (an_idx >> ANON_CHUNK_SHIFT));
571 335
572 336 if (mdb_vread(&anon_ptr, sizeof (anon_ptr), anon_addr) !=
573 337 sizeof (anon_ptr)) {
574 338 mdb_warn("Failed to read anon_ptr from %p (2a level)\n",
575 339 anon_addr);
576 340 return (0);
577 341 }
578 342
579 343 if (anon_ptr == 0) {
580 344 return (0);
581 345 }
582 346
583 347 anon_addr = anon_ptr + (sizeof (anon_ptr) *
584 348 (an_idx & ANON_CHUNK_OFF));
585 349 if (mdb_vread(&anon_ptr, sizeof (anon_ptr), anon_addr) !=
586 350 sizeof (anon_ptr)) {
587 351 mdb_warn("Failed to read anon_ptr from %p (2b level)\n",
588 352 anon_addr);
589 353 return (0);
590 354 }
591 355
592 356 return (anon_ptr & ANON_PTRMASK);
593 357 }
594 358
595 359 static void
596 360 gcore_anon_get(uintptr_t ahp, ulong_t an_index, uintptr_t *vp, u_offset_t *off)
597 361 {
598 362 mdb_anon_t anon;
599 363 uintptr_t ap;
600 364
601 365 ap = gcore_anon_get_ptr(ahp, an_index);
602 366 if (ap != 0) {
603 367 if (mdb_ctf_vread(&anon, "struct anon", "mdb_anon_t", ap, 0) ==
604 368 -1) {
605 369 return;
606 370 }
607 371
608 372 *vp = anon.an_vp;
609 373 *off = anon.an_off;
610 374 } else {
611 375 *vp = 0;
612 376 *off = 0;
613 377 }
614 378 }
615 379
616 380 static u_offset_t
617 381 gsvn_incore(gcore_seg_t *gs, u_offset_t addr, u_offset_t eaddr)
618 382 {
619 383 mdb_segvn_data_t *svd = gs->gs_data;
620 384 mdb_seg_t *seg = gs->gs_seg;
621 385 mdb_amp_t amp;
622 386 u_offset_t offset;
623 387 uintptr_t vp;
624 388 size_t p, ep;
625 389
626 390 if (svd->amp != 0 && mdb_ctf_vread(&, "amp_t", "mdb_amp_t", svd->amp,
627 391 0) == -1) {
628 392 return (eaddr);
629 393 }
630 394
631 395 p = seg_page(seg, addr);
632 396 ep = seg_page(seg, eaddr);
633 397 for (; p < ep; p++, addr += PAGESIZE) {
634 398 /* First check the anon map */
635 399 if (svd->amp != 0) {
636 400 gcore_anon_get(amp.ahp, svd->anon_index + p, &vp,
637 401 &offset);
638 402 if (vp != 0 && mdb_page_lookup(vp, offset) != 0) {
639 403 break;
640 404 }
641 405 }
642 406
643 407 /* Now check the segment's vnode */
644 408 vp = svd->vp;
645 409 offset = svd->offset + (addr - gs->gs_seg->s_base);
646 410 if (mdb_page_lookup(vp, offset) != 0) {
647 411 break;
648 412 }
649 413
650 414 dprintf("amp: %p vp: %p addr: %p offset: %p not in core!\n",
651 415 svd->amp, svd->vp, addr, offset);
652 416 }
653 417
654 418 return (addr);
655 419 }
656 420
657 421 static uint_t
658 422 gsvn_getprot(gcore_seg_t *gs, u_offset_t addr)
659 423 {
660 424 mdb_segvn_data_t *svd = gs->gs_data;
661 425 mdb_seg_t *seg = gs->gs_seg;
662 426
663 427 if (svd->pageprot == 0) {
664 428 return (svd->prot);
665 429 }
666 430
667 431 dprintf("addr: %p pgno: %p\n", addr, seg_page(seg, addr));
668 432 return (VPP_PROT(&svd->vpage[seg_page(seg, addr)]));
669 433 }
670 434
671 435 /*
672 436 * Helper functions for constructing the process address space maps.
673 437 */
674 438 /*ARGSUSED*/
675 439 static int
676 440 as_segat_cb(uintptr_t seg_addr, const void *aw_buff, void *arg)
677 441 {
678 442 as_segat_cbarg_t *as_segat_arg = arg;
679 443 mdb_seg_t seg;
680 444
681 445 if (mdb_ctf_vread(&seg, "struct seg", "mdb_seg_t", seg_addr, 0) == -1) {
682 446 return (WALK_ERR);
683 447 }
684 448
685 449 if (as_segat_arg->addr < seg.s_base) {
686 450 return (WALK_NEXT);
687 451 }
688 452
689 453 if (as_segat_arg->addr >= seg.s_base + seg.s_size) {
690 454 return (WALK_NEXT);
691 455 }
692 456
693 457 as_segat_arg->res = seg_addr;
694 458 return (WALK_DONE);
695 459 }
696 460
697 461 /*
698 462 * Find a segment containing addr.
699 463 */
700 464 static uintptr_t
701 465 gcore_as_segat(uintptr_t as_addr, uintptr_t addr)
702 466 {
703 467 as_segat_cbarg_t as_segat_arg;
704 468 uintptr_t segtree_addr;
705 469
706 470 as_segat_arg.addr = addr;
707 471 as_segat_arg.res = 0;
708 472
709 473 segtree_addr = as_addr + mdb_ctf_offsetof_by_name("struct as",
710 474 "a_segtree");
711 475 (void) avl_walk_mdb(segtree_addr, as_segat_cb, &as_segat_arg);
712 476
713 477 return (as_segat_arg.res);
714 478 }
715 479
716 480 static uintptr_t
↓ open down ↓ |
368 lines elided |
↑ open up ↑ |
717 481 gcore_break_seg(mdb_proc_t *p)
718 482 {
719 483 uintptr_t addr = p->p_brkbase;
720 484
721 485 if (p->p_brkbase != 0)
722 486 addr += p->p_brksize - 1;
723 487
724 488 return (gcore_as_segat(p->p_as, addr));
725 489 }
726 490
727 -/* ISA dependent function. */
728 -static uintptr_t
729 -gcore_prgetstackbase(mdb_proc_t *p)
730 -{
731 - return (p->p_usrstack - p->p_stksize);
732 -}
733 -
734 491 static u_offset_t
735 492 gcore_vnode_size(uintptr_t vnode_addr)
736 493 {
737 494 mdb_vnode_t vnode;
738 495 mdb_vnodeops_t vnodeops;
739 496 char vops_name[128];
740 497
741 498 if (mdb_ctf_vread(&vnode, "vnode_t", "mdb_vnode_t", vnode_addr, 0) ==
742 499 -1) {
743 500 return (-1);
744 501 }
745 502
746 503 if (mdb_ctf_vread(&vnodeops, "vnodeops_t", "mdb_vnodeops_t",
747 504 vnode.v_op, 0) == -1) {
748 505 return (-1);
749 506 }
750 507
751 508 if (mdb_readstr(vops_name, sizeof (vops_name), vnodeops.vnop_name) ==
752 509 -1) {
753 510 mdb_warn("Failed to read vnop_name from %p\n",
754 511 vnodeops.vnop_name);
755 512 return (-1);
756 513 }
757 514
758 515 if (strcmp(vops_name, "zfs") == 0) {
759 516 mdb_znode_t znode;
760 517
761 518 if (mdb_ctf_vread(&znode, "znode_t", "mdb_znode_t",
762 519 vnode.v_data, 0) == -1) {
763 520 return (-1);
764 521 }
765 522 return (znode.z_size);
766 523 }
767 524
768 525 if (strcmp(vops_name, "tmpfs") == 0) {
769 526 mdb_tmpnode_t tnode;
770 527
771 528 if (mdb_ctf_vread(&tnode, "struct tmpnode", "mdb_tmpnode_t",
772 529 vnode.v_data, 0) == -1) {
773 530 return (-1);
774 531 }
775 532 return (tnode.tn_attr.va_size);
776 533 }
777 534
778 535 /* Unknown file system type. */
779 536 mdb_warn("Unknown fs type: %s\n", vops_name);
780 537 return (-1);
781 538 }
782 539
783 540 static uint64_t
784 541 gcore_pr_getsegsize(mdb_seg_t *seg)
785 542 {
786 543 uint64_t size = seg->s_size;
787 544
788 545 if (seg->s_ops == gcore_segvn_ops) {
789 546 mdb_segvn_data_t svd;
790 547
791 548 if (mdb_ctf_vread(&svd, "segvn_data_t", "mdb_segvn_data_t",
792 549 seg->s_data, 0) == -1) {
793 550 return (-1);
794 551 }
795 552
796 553 if (svd.vp != 0) {
797 554 u_offset_t fsize;
798 555 u_offset_t offset;
799 556
800 557 fsize = gcore_vnode_size(svd.vp);
801 558 if (fsize == -1) {
802 559 return (-1);
803 560 }
804 561 offset = svd.offset;
805 562
806 563 if (fsize < offset) {
807 564 fsize = 0;
808 565 } else {
809 566 fsize -= offset;
810 567 }
811 568
812 569 fsize = roundup(fsize, PAGESIZE);
813 570 }
814 571
815 572 return (size);
816 573 }
817 574
818 575 return (size);
819 576 }
820 577
821 578 /*ARGSUSED*/
822 579 static int
823 580 gcore_getwatchprot_cb(uintptr_t node_addr, const void *aw_buff, void *arg)
824 581 {
825 582 getwatchprot_cbarg_t *cbarg = arg;
826 583
827 584 if (mdb_ctf_vread(&cbarg->wp, "struct watched_page",
828 585 "mdb_watched_page_t", node_addr, 0) == -1) {
829 586 return (WALK_ERR);
830 587 }
831 588
832 589 if (cbarg->wp.wp_vaddr == cbarg->wp_vaddr) {
833 590 cbarg->found = B_TRUE;
834 591 return (WALK_DONE);
835 592 }
836 593
837 594 return (WALK_NEXT);
838 595 }
839 596
840 597 static void
841 598 gcore_getwatchprot(uintptr_t as_addr, u_offset_t addr, uint_t *prot)
842 599 {
843 600 getwatchprot_cbarg_t cbarg;
844 601 uintptr_t wp_addr;
845 602
846 603 cbarg.wp_vaddr = (uintptr_t)addr & (uintptr_t)PAGEMASK;
847 604 cbarg.found = B_FALSE;
848 605
849 606 wp_addr = as_addr + mdb_ctf_offsetof_by_name("struct as", "a_wpage");
850 607 (void) avl_walk_mdb(wp_addr, gcore_getwatchprot_cb, &cbarg);
851 608
852 609 if (cbarg.found) {
853 610 *prot = cbarg.wp.wp_oprot;
854 611 }
855 612 }
856 613
857 614 static u_offset_t
858 615 gcore_pr_nextprot(gcore_seg_t *gs, u_offset_t *saddrp, u_offset_t eaddr,
859 616 uint_t *protp)
860 617 {
861 618 uint_t prot, nprot;
862 619 u_offset_t addr = *saddrp;
863 620 uintptr_t as_addr = gs->gs_seg->s_as;
864 621 int noreserve = 0;
865 622
866 623 noreserve = GSOP_NORESERVE(gs);
867 624 dprintf("addr: %p noreserve: %d\n", addr, noreserve);
868 625
869 626 if (noreserve) {
870 627 addr = GSOP_INCORE(gs, addr, eaddr);
871 628 if (addr == eaddr) {
872 629 prot = 0;
873 630 *saddrp = addr;
874 631 goto out;
875 632 }
876 633 }
877 634
878 635 prot = GSOP_GETPROT(gs, addr);
879 636 gcore_getwatchprot(as_addr, addr, &prot);
880 637 *saddrp = addr;
881 638
882 639 for (addr += PAGESIZE; addr < eaddr; addr += PAGESIZE) {
883 640 /* Discontinuity */
884 641 if (noreserve && GSOP_INCORE(gs, addr, eaddr) != addr) {
885 642 goto out;
886 643 }
887 644
888 645 nprot = GSOP_GETPROT(gs, addr);
889 646 gcore_getwatchprot(as_addr, addr, &nprot);
890 647
891 648 if (nprot != prot) {
892 649 break;
893 650 }
894 651 }
895 652
896 653 out:
897 654 *protp = prot;
898 655 return (addr);
899 656 }
900 657
901 658 /*
902 659 * Get the page protection for the given start address.
903 660 * - saddrp: in - start address
904 661 * out - contains address of first in core page
905 662 * - naddrp: out - address of next in core page that has different protection
906 663 * - eaddr: in - end address
907 664 */
908 665 static uint_t
909 666 gcore_pr_getprot(gcore_seg_t *gs, u_offset_t *saddrp, u_offset_t *naddrp,
910 667 u_offset_t eaddr)
911 668 {
912 669 u_offset_t naddr;
913 670 uint_t prot;
914 671
915 672 dprintf("seg: %p saddr: %p eaddr: %p\n",
916 673 gs->gs_seg, *saddrp, eaddr);
917 674
918 675 naddr = gcore_pr_nextprot(gs, saddrp, eaddr, &prot);
919 676
920 677 dprintf("seg: %p saddr: %p naddr: %p eaddr: %p\n",
921 678 gs->gs_seg, *saddrp, naddr, eaddr);
922 679
923 680 *naddrp = naddr;
924 681 return (prot);
925 682 }
926 683
927 684 static gcore_seg_t *
928 685 gcore_seg_create(mdb_seg_t *seg)
929 686 {
930 687 gcore_seg_t *gs;
931 688
932 689 gs = mdb_alloc(sizeof (*gs), UM_SLEEP);
933 690 gs->gs_seg = seg;
934 691 if (seg->s_ops == gcore_segvn_ops) {
935 692 gs->gs_ops = &gsvn_ops;
936 693 } else {
937 694 mdb_warn("Unhandled segment type, ops: %p\n", seg->s_ops);
938 695 goto error;
939 696 }
940 697
941 698 if (GSOP_INIT(gs) != 0) {
942 699 goto error;
943 700 }
944 701
945 702 return (gs);
946 703
947 704 error:
948 705 mdb_free(gs, sizeof (*gs));
949 706 return (NULL);
950 707 }
951 708
952 709 static void
953 710 gcore_seg_destroy(gcore_seg_t *gs)
954 711 {
955 712 GSOP_FINI(gs);
956 713 mdb_free(gs, sizeof (*gs));
957 714 }
958 715
959 716 /*ARGSUSED*/
960 717 static int
961 718 read_maps_cb(uintptr_t seg_addr, const void *aw_buff, void *arg)
962 719 {
963 720 read_maps_cbarg_t *cbarg = arg;
964 721 mdb_segvn_data_t svd;
965 722 mdb_seg_t s;
966 723 mdb_seg_t *seg;
967 724 uint_t prot;
968 725 gcore_seg_t *gs;
969 726 uintptr_t eaddr;
970 727 u_offset_t saddr, baddr;
971 728 prmap_node_t *mnode;
972 729 prmap_t *mp;
973 730
974 731 if (mdb_ctf_vread(&s, "struct seg", "mdb_seg_t", seg_addr, 0) == -1) {
975 732 return (WALK_ERR);
976 733 }
977 734 seg = &s;
978 735 eaddr = seg->s_base + gcore_pr_getsegsize(seg);
979 736
980 737 if ((gs = gcore_seg_create(seg)) == NULL) {
981 738 mdb_warn("gcore_seg_create failed!\n");
982 739 return (WALK_ERR);
983 740 }
984 741
985 742 /*
986 743 * Iterate from the base of the segment to its end, allocating a new
987 744 * prmap_node at each address boundary (baddr) between ranges that
988 745 * have different virtual memory protections.
989 746 */
990 747 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
991 748 prot = gcore_pr_getprot(gs, &saddr, &baddr, eaddr);
992 749 if (saddr == eaddr) {
993 750 break;
994 751 }
995 752
996 753 mnode = mdb_alloc(sizeof (*mnode), UM_SLEEP);
997 754 mnode->next = NULL;
998 755 mp = &mnode->m;
999 756
1000 757 if (cbarg->map_head == NULL) {
1001 758 cbarg->map_head = cbarg->map_tail = mnode;
1002 759 } else {
1003 760 cbarg->map_tail->next = mnode;
1004 761 cbarg->map_tail = mnode;
1005 762 }
1006 763 cbarg->map_len++;
1007 764
1008 765 mp->pr_vaddr = (uintptr_t)saddr;
1009 766 mp->pr_size = baddr - saddr;
1010 767 mp->pr_offset = GSOP_GETOFFSET(gs, saddr);
1011 768 mp->pr_mflags = 0;
1012 769 if (prot & PROT_READ)
1013 770 mp->pr_mflags |= MA_READ;
1014 771 if (prot & PROT_WRITE)
1015 772 mp->pr_mflags |= MA_WRITE;
1016 773 if (prot & PROT_EXEC)
1017 774 mp->pr_mflags |= MA_EXEC;
1018 775 if (GSOP_GETTYPE(gs, saddr) & MAP_SHARED)
1019 776 mp->pr_mflags |= MA_SHARED;
1020 777 if (GSOP_GETTYPE(gs, saddr) & MAP_NORESERVE)
1021 778 mp->pr_mflags |= MA_NORESERVE;
1022 779 if (seg->s_ops == gcore_segvn_ops) {
1023 780 if (mdb_ctf_vread(&svd, "segvn_data_t",
1024 781 "mdb_segvn_data_t", seg->s_data, 0) == 0 &&
1025 782 svd.vp == NULL) {
1026 783 mp->pr_mflags |= MA_ANON;
1027 784 }
1028 785 }
1029 786 if (seg_addr == cbarg->brkseg)
1030 787 mp->pr_mflags |= MA_BREAK;
1031 788 else if (seg_addr == cbarg->stkseg)
1032 789 mp->pr_mflags |= MA_STACK;
1033 790
1034 791 mp->pr_pagesize = PAGESIZE;
1035 792
1036 793 /*
1037 794 * Manufacture a filename for the "object" dir.
1038 795 */
1039 796 GSOP_NAME(gs, mp->pr_mapname, sizeof (mp->pr_mapname));
1040 797 }
1041 798
1042 799 gcore_seg_destroy(gs);
1043 800
1044 801 return (0);
1045 802 }
1046 803
1047 804 /*
1048 805 * Helper functions for retrieving process and lwp state.
1049 806 */
1050 807 static int
1051 808 pcommon_init(mdb_proc_t *p, pcommon_t *pc)
1052 809 {
1053 810 mdb_pid_t pid;
1054 811 mdb_sess_t sess;
1055 812 mdb_task_t task;
1056 813 mdb_kproject_t proj;
1057 814 mdb_zone_t zone;
1058 815
1059 816 pc->pc_nlwp = p->p_lwpcnt;
1060 817 pc->pc_nzomb = p->p_zombcnt;
1061 818
1062 819 if (mdb_ctf_vread(&pid, "struct pid", "mdb_pid_t", p->p_pidp, 0) ==
1063 820 -1) {
1064 821 return (-1);
1065 822 }
1066 823 pc->pc_pid = pid.pid_id;
1067 824 pc->pc_ppid = p->p_ppid;
1068 825
1069 826 if (mdb_ctf_vread(&pid, "struct pid", "mdb_pid_t", p->p_pgidp, 0) ==
1070 827 -1) {
1071 828 return (-1);
1072 829 }
1073 830 pc->pc_pgid = pid.pid_id;
1074 831
1075 832 if (mdb_ctf_vread(&sess, "sess_t", "mdb_sess_t", p->p_sessp, 0) ==
1076 833 -1) {
1077 834 return (-1);
1078 835 }
1079 836 if (mdb_ctf_vread(&pid, "struct pid", "mdb_pid_t", sess.s_sidp, 0) ==
1080 837 -1) {
1081 838 return (-1);
1082 839 }
1083 840 pc->pc_sid = pid.pid_id;
1084 841
1085 842 if (mdb_ctf_vread(&task, "task_t", "mdb_task_t", p->p_task, 0) == -1) {
1086 843 return (-1);
1087 844 }
1088 845 pc->pc_taskid = task.tk_tkid;
1089 846
1090 847 if (mdb_ctf_vread(&proj, "kproject_t", "mdb_kproject_t", task.tk_proj,
1091 848 0) == -1) {
1092 849 return (-1);
1093 850 }
1094 851 pc->pc_projid = proj.kpj_id;
1095 852
1096 853 if (mdb_ctf_vread(&zone, "zone_t", "mdb_zone_t", p->p_zone, 0) == -1) {
1097 854 return (-1);
1098 855 }
1099 856 pc->pc_zoneid = zone.zone_id;
1100 857
1101 858 switch (p->p_model) {
1102 859 case DATAMODEL_ILP32:
1103 860 pc->pc_dmodel = PR_MODEL_ILP32;
1104 861 break;
1105 862 case DATAMODEL_LP64:
1106 863 pc->pc_dmodel = PR_MODEL_LP64;
1107 864 break;
1108 865 }
1109 866
1110 867 return (0);
1111 868 }
1112 869
1113 870 static uintptr_t
1114 871 gcore_prchoose(mdb_proc_t *p)
1115 872 {
1116 873 mdb_kthread_t kthr;
1117 874 mdb_kthread_t *t = &kthr;
1118 875 ushort_t t_istop_whystop = 0;
1119 876 ushort_t t_istop_whatstop = 0;
1120 877 uintptr_t t_addr = NULL;
1121 878 uintptr_t t_onproc = NULL; // running on processor
1122 879 uintptr_t t_run = NULL; // runnable, on disp queue
1123 880 uintptr_t t_sleep = NULL; // sleeping
1124 881 uintptr_t t_susp = NULL; // suspended stop
1125 882 uintptr_t t_jstop = NULL; // jobcontrol stop, w/o directed stop
1126 883 uintptr_t t_jdstop = NULL; // jobcontrol stop with directed stop
1127 884 uintptr_t t_req = NULL; // requested stop
1128 885 uintptr_t t_istop = NULL; // event-of-interest stop
1129 886 uintptr_t t_dtrace = NULL; // DTrace stop
1130 887
1131 888 /*
1132 889 * If the agent lwp exists, it takes precedence over all others.
1133 890 */
1134 891 if ((t_addr = p->p_agenttp) != NULL) {
1135 892 return (t_addr);
1136 893 }
1137 894
1138 895 if ((t_addr = p->p_tlist) == NULL) /* start at the head of the list */
1139 896 return (t_addr);
1140 897 do { /* for each lwp in the process */
1141 898 if (mdb_ctf_vread(&kthr, "kthread_t", "mdb_kthread_t",
1142 899 t_addr, 0) == -1) {
1143 900 return (0);
1144 901 }
1145 902
1146 903 if (VSTOPPED(t)) { /* virtually stopped */
1147 904 if (t_req == NULL)
1148 905 t_req = t_addr;
1149 906 continue;
1150 907 }
1151 908
1152 909 switch (t->t_state) {
1153 910 default:
1154 911 return (0);
1155 912 case TS_SLEEP:
1156 913 if (t_sleep == NULL)
1157 914 t_sleep = t_addr;
1158 915 break;
1159 916 case TS_RUN:
1160 917 case TS_WAIT:
1161 918 if (t_run == NULL)
1162 919 t_run = t_addr;
1163 920 break;
1164 921 case TS_ONPROC:
1165 922 if (t_onproc == NULL)
1166 923 t_onproc = t_addr;
1167 924 break;
1168 925 /*
1169 926 * Threads in the zombie state have the lowest
1170 927 * priority when selecting a representative lwp.
1171 928 */
1172 929 case TS_ZOMB:
1173 930 break;
1174 931 case TS_STOPPED:
1175 932 switch (t->t_whystop) {
1176 933 case PR_SUSPENDED:
1177 934 if (t_susp == NULL)
1178 935 t_susp = t_addr;
1179 936 break;
1180 937 case PR_JOBCONTROL:
1181 938 if (t->t_proc_flag & TP_PRSTOP) {
1182 939 if (t_jdstop == NULL)
1183 940 t_jdstop = t_addr;
1184 941 } else {
1185 942 if (t_jstop == NULL)
1186 943 t_jstop = t_addr;
1187 944 }
1188 945 break;
1189 946 case PR_REQUESTED:
1190 947 if (t->t_dtrace_stop && t_dtrace == NULL)
1191 948 t_dtrace = t_addr;
1192 949 else if (t_req == NULL)
1193 950 t_req = t_addr;
1194 951 break;
1195 952 case PR_SYSENTRY:
1196 953 case PR_SYSEXIT:
1197 954 case PR_SIGNALLED:
1198 955 case PR_FAULTED:
1199 956 /*
1200 957 * Make an lwp calling exit() be the
1201 958 * last lwp seen in the process.
1202 959 */
1203 960 if (t_istop == NULL ||
1204 961 (t_istop_whystop == PR_SYSENTRY &&
1205 962 t_istop_whatstop == SYS_exit)) {
1206 963 t_istop = t_addr;
1207 964 t_istop_whystop = t->t_whystop;
1208 965 t_istop_whatstop = t->t_whatstop;
1209 966 }
1210 967 break;
1211 968 case PR_CHECKPOINT: /* can't happen? */
1212 969 break;
1213 970 default:
1214 971 return (0);
1215 972 }
1216 973 break;
1217 974 }
1218 975 } while ((t_addr = t->t_forw) != p->p_tlist);
1219 976
1220 977 if (t_onproc)
1221 978 t_addr = t_onproc;
1222 979 else if (t_run)
1223 980 t_addr = t_run;
1224 981 else if (t_sleep)
1225 982 t_addr = t_sleep;
1226 983 else if (t_jstop)
1227 984 t_addr = t_jstop;
1228 985 else if (t_jdstop)
1229 986 t_addr = t_jdstop;
1230 987 else if (t_istop)
1231 988 t_addr = t_istop;
1232 989 else if (t_dtrace)
1233 990 t_addr = t_dtrace;
1234 991 else if (t_req)
1235 992 t_addr = t_req;
1236 993 else if (t_susp)
1237 994 t_addr = t_susp;
1238 995 else /* TS_ZOMB */
1239 996 t_addr = p->p_tlist;
1240 997
1241 998 return (t_addr);
1242 999 }
1243 1000
1244 1001 /*
1245 1002 * Fields not populated:
1246 1003 * - pr_stype
1247 1004 * - pr_oldpri
1248 1005 * - pr_nice
1249 1006 * - pr_time
1250 1007 * - pr_pctcpu
1251 1008 * - pr_cpu
1252 1009 */
1253 1010 static int
1254 1011 gcore_prgetlwpsinfo(uintptr_t t_addr, mdb_kthread_t *t, lwpsinfo_t *psp)
1255 1012 {
1256 1013 char c, state;
1257 1014 mdb_cpu_t cpu;
1258 1015 mdb_lpl_t lgrp;
1259 1016 uintptr_t str_addr;
1260 1017
1261 1018 bzero(psp, sizeof (*psp));
1262 1019
1263 1020 psp->pr_flag = 0; /* lwpsinfo_t.pr_flag is deprecated */
1264 1021 psp->pr_lwpid = t->t_tid;
1265 1022 psp->pr_addr = t_addr;
1266 1023 psp->pr_wchan = (uintptr_t)t->t_wchan;
1267 1024
1268 1025 /* map the thread state enum into a process state enum */
1269 1026 state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
1270 1027 switch (state) {
1271 1028 case TS_SLEEP: state = SSLEEP; c = 'S'; break;
1272 1029 case TS_RUN: state = SRUN; c = 'R'; break;
1273 1030 case TS_ONPROC: state = SONPROC; c = 'O'; break;
1274 1031 case TS_ZOMB: state = SZOMB; c = 'Z'; break;
1275 1032 case TS_STOPPED: state = SSTOP; c = 'T'; break;
1276 1033 case TS_WAIT: state = SWAIT; c = 'W'; break;
1277 1034 default: state = 0; c = '?'; break;
1278 1035 }
1279 1036 psp->pr_state = state;
1280 1037 psp->pr_sname = c;
1281 1038 psp->pr_syscall = t->t_sysnum;
1282 1039 psp->pr_pri = t->t_pri;
1283 1040 psp->pr_start.tv_sec = t->t_start;
1284 1041 psp->pr_start.tv_nsec = 0L;
1285 1042
1286 1043 str_addr = (uintptr_t)gcore_sclass[t->t_cid].cl_name;
1287 1044 if (mdb_readstr(psp->pr_clname, sizeof (psp->pr_clname) - 1, str_addr)
1288 1045 == -1) {
1289 1046 mdb_warn("Failed to read string from %p\n", str_addr);
1290 1047 return (-1);
1291 1048 }
1292 1049 bzero(psp->pr_name, sizeof (psp->pr_name));
1293 1050
1294 1051 if (mdb_ctf_vread(&cpu, "struct cpu", "mdb_cpu_t", t->t_cpu, 0) == -1) {
1295 1052 return (-1);
1296 1053 }
1297 1054 psp->pr_onpro = cpu.cpu_id;
1298 1055 psp->pr_bindpro = t->t_bind_cpu;
1299 1056 psp->pr_bindpset = t->t_bind_pset;
1300 1057
1301 1058 if (mdb_ctf_vread(&lgrp, "lpl_t", "mdb_lpl_t", t->t_lpl, 0) == -1) {
1302 1059 return (-1);
1303 1060 }
1304 1061 psp->pr_lgrp = lgrp.lpl_lgrpid;
1305 1062
1306 1063 return (0);
1307 1064 }
1308 1065
1309 1066 /*ARGSUSED*/
1310 1067 static int
1311 1068 gcore_lpsinfo_cb(mdb_proc_t *p, lwpent_t *lwent, void *data)
1312 1069 {
1313 1070 lwpsinfo_t *lpsinfo = data;
1314 1071 uintptr_t t_addr = (uintptr_t)lwent->le_thread;
1315 1072 mdb_kthread_t kthrd;
1316 1073
1317 1074 if (t_addr != 0) {
1318 1075 if (mdb_ctf_vread(&kthrd, "kthread_t", "mdb_kthread_t", t_addr,
1319 1076 0) == -1) {
1320 1077 return (-1);
1321 1078 }
1322 1079 return (gcore_prgetlwpsinfo(t_addr, &kthrd, lpsinfo));
1323 1080 }
1324 1081
1325 1082 bzero(lpsinfo, sizeof (*lpsinfo));
1326 1083 lpsinfo->pr_lwpid = lwent->le_lwpid;
1327 1084 lpsinfo->pr_state = SZOMB;
1328 1085 lpsinfo->pr_sname = 'Z';
1329 1086 lpsinfo->pr_start.tv_sec = lwent->le_start;
1330 1087 lpsinfo->pr_bindpro = PBIND_NONE;
1331 1088 lpsinfo->pr_bindpset = PS_NONE;
1332 1089 return (0);
1333 1090 }
1334 1091
1335 1092 static void
1336 1093 gcore_schedctl_finish_sigblock(mdb_kthread_t *t)
1337 1094 {
1338 1095 mdb_sc_shared_t td;
1339 1096 mdb_sc_shared_t *tdp;
1340 1097
1341 1098 if (t->t_schedctl == NULL) {
1342 1099 return;
1343 1100 }
1344 1101
1345 1102 if (mdb_ctf_vread(&td, "sc_shared_t", "mdb_sc_shared_t", t->t_schedctl,
1346 1103 0) == -1) {
1347 1104 return;
1348 1105 }
1349 1106 tdp = &td;
1350 1107
1351 1108 if (tdp->sc_sigblock) {
1352 1109 t->t_hold.__sigbits[0] = FILLSET0 & ~CANTMASK0;
1353 1110 t->t_hold.__sigbits[1] = FILLSET1 & ~CANTMASK1;
1354 1111 t->t_hold.__sigbits[2] = FILLSET2 & ~CANTMASK2;
1355 1112 tdp->sc_sigblock = 0;
1356 1113 }
1357 1114 }
1358 1115
1359 1116 static void
1360 1117 gcore_prgetaction(mdb_proc_t *p, user_t *up, uint_t sig, struct sigaction *sp)
1361 1118 {
1362 1119 int nsig = NSIG;
1363 1120
1364 1121 bzero(sp, sizeof (*sp));
1365 1122
1366 1123 if (sig != 0 && (unsigned)sig < nsig) {
1367 1124 sp->sa_handler = up->u_signal[sig-1];
1368 1125 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1369 1126 if (sigismember(&up->u_sigonstack, sig))
1370 1127 sp->sa_flags |= SA_ONSTACK;
1371 1128 if (sigismember(&up->u_sigresethand, sig))
1372 1129 sp->sa_flags |= SA_RESETHAND;
1373 1130 if (sigismember(&up->u_sigrestart, sig))
1374 1131 sp->sa_flags |= SA_RESTART;
1375 1132 if (sigismember(&p->p_siginfo, sig))
1376 1133 sp->sa_flags |= SA_SIGINFO;
1377 1134 if (sigismember(&up->u_signodefer, sig))
↓ open down ↓ |
634 lines elided |
↑ open up ↑ |
1378 1135 sp->sa_flags |= SA_NODEFER;
1379 1136 if (sig == SIGCLD) {
1380 1137 if (p->p_flag & SNOWAIT)
1381 1138 sp->sa_flags |= SA_NOCLDWAIT;
1382 1139 if ((p->p_flag & SJCTL) == 0)
1383 1140 sp->sa_flags |= SA_NOCLDSTOP;
1384 1141 }
1385 1142 }
1386 1143 }
1387 1144
1388 -/* ISA dependent function. */
1389 -static int
1390 -gcore_prfetchinstr(mdb_klwp_t *lwp, ulong_t *ip)
1391 -{
1392 - *ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
1393 - return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
1394 -}
1395 -
1396 -/* ISA dependent function. */
1397 -static int
1398 -gcore_prisstep(mdb_klwp_t *lwp)
1399 -{
1400 - return ((lwp->lwp_pcb.pcb_flags &
1401 - (NORMAL_STEP|WATCH_STEP|DEBUG_PENDING)) != 0);
1402 -}
1403 -
1404 -/* ISA dependent function. */
1405 -static void
1406 -gcore_getgregs(mdb_klwp_t *lwp, gregset_t grp)
1407 -{
1408 - struct regs rgs;
1409 - struct regs *rp;
1410 -
1411 - if (mdb_vread(&rgs, sizeof (rgs), lwp->lwp_regs) != sizeof (rgs)) {
1412 - mdb_warn("Failed to read regs from %p\n", lwp->lwp_regs);
1413 - return;
1414 - }
1415 - rp = &rgs;
1416 -
1417 -#if defined(__amd64)
1418 - struct pcb *pcb = &lwp->lwp_pcb;
1419 -
1420 - grp[REG_RDI] = rp->r_rdi;
1421 - grp[REG_RSI] = rp->r_rsi;
1422 - grp[REG_RDX] = rp->r_rdx;
1423 - grp[REG_RCX] = rp->r_rcx;
1424 - grp[REG_R8] = rp->r_r8;
1425 - grp[REG_R9] = rp->r_r9;
1426 - grp[REG_RAX] = rp->r_rax;
1427 - grp[REG_RBX] = rp->r_rbx;
1428 - grp[REG_RBP] = rp->r_rbp;
1429 - grp[REG_R10] = rp->r_r10;
1430 - grp[REG_R11] = rp->r_r11;
1431 - grp[REG_R12] = rp->r_r12;
1432 - grp[REG_R13] = rp->r_r13;
1433 - grp[REG_R14] = rp->r_r14;
1434 - grp[REG_R15] = rp->r_r15;
1435 - grp[REG_FSBASE] = pcb->pcb_fsbase;
1436 - grp[REG_GSBASE] = pcb->pcb_gsbase;
1437 - if (pcb->pcb_rupdate == 1) {
1438 - grp[REG_DS] = pcb->pcb_ds;
1439 - grp[REG_ES] = pcb->pcb_es;
1440 - grp[REG_FS] = pcb->pcb_fs;
1441 - grp[REG_GS] = pcb->pcb_gs;
1442 - } else {
1443 - grp[REG_DS] = rp->r_ds;
1444 - grp[REG_ES] = rp->r_es;
1445 - grp[REG_FS] = rp->r_fs;
1446 - grp[REG_GS] = rp->r_gs;
1447 - }
1448 - grp[REG_TRAPNO] = rp->r_trapno;
1449 - grp[REG_ERR] = rp->r_err;
1450 - grp[REG_RIP] = rp->r_rip;
1451 - grp[REG_CS] = rp->r_cs;
1452 - grp[REG_SS] = rp->r_ss;
1453 - grp[REG_RFL] = rp->r_rfl;
1454 - grp[REG_RSP] = rp->r_rsp;
1455 -#else
1456 - bcopy(&rp->r_gs, grp, sizeof (gregset_t));
1457 -#endif
1458 -}
1459 -
1460 -/* ISA dependent functions. */
1461 -static int
1462 -gcore_prgetrvals(mdb_klwp_t *lwp, long *rval1, long *rval2)
1463 -{
1464 - struct regs *r = lwptoregs(lwp);
1465 -
1466 - if (r->r_ps & PS_C)
1467 - return (r->r_r0);
1468 - if (lwp->lwp_eosys == JUSTRETURN) {
1469 - *rval1 = 0;
1470 - *rval2 = 0;
1471 - } else {
1472 - *rval1 = r->r_r0;
1473 - *rval2 = r->r_r1;
1474 - }
1475 - return (0);
1476 -}
1477 -
1478 1145 static void
1479 1146 gcore_prgetprregs(mdb_klwp_t *lwp, prgregset_t prp)
1480 1147 {
1481 1148 gcore_getgregs(lwp, prp);
1482 1149 }
1483 1150
1484 1151 /*
1485 1152 * Field not populated:
1486 1153 * - pr_tstamp
1487 1154 * - pr_utime
1488 1155 * - pr_stime
1489 1156 * - pr_syscall
1490 1157 * - pr_syarg
1491 1158 * - pr_nsysarg
1492 1159 * - pr_fpreg
1493 1160 */
1494 1161 /*ARGSUSED*/
1495 1162 static int
1496 1163 gcore_prgetlwpstatus(mdb_proc_t *p, uintptr_t t_addr, mdb_kthread_t *t,
1497 1164 lwpstatus_t *sp, zone_t *zp)
1498 1165 {
1499 1166 uintptr_t lwp_addr = ttolwp(t);
1500 1167 mdb_klwp_t lw;
1501 1168 mdb_klwp_t *lwp;
1502 1169 ulong_t instr;
1503 1170 int flags;
1504 1171 uintptr_t str_addr;
1505 1172 struct pid pid;
1506 1173
1507 1174 if (mdb_ctf_vread(&lw, "klwp_t", "mdb_klwp_t", lwp_addr, 0) == -1) {
1508 1175 return (-1);
1509 1176 }
1510 1177 lwp = &lw;
1511 1178
1512 1179 bzero(sp, sizeof (*sp));
1513 1180 flags = 0L;
1514 1181 if (t->t_state == TS_STOPPED) {
1515 1182 flags |= PR_STOPPED;
1516 1183 if ((t->t_schedflag & TS_PSTART) == 0)
1517 1184 flags |= PR_ISTOP;
1518 1185 } else if (VSTOPPED(t)) {
1519 1186 flags |= PR_STOPPED|PR_ISTOP;
1520 1187 }
1521 1188 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
1522 1189 flags |= PR_DSTOP;
1523 1190 if (lwp->lwp_asleep)
1524 1191 flags |= PR_ASLEEP;
1525 1192 if (t_addr == p->p_agenttp)
1526 1193 flags |= PR_AGENT;
1527 1194 if (!(t->t_proc_flag & TP_TWAIT))
1528 1195 flags |= PR_DETACH;
1529 1196 if (t->t_proc_flag & TP_DAEMON)
1530 1197 flags |= PR_DAEMON;
1531 1198 if (p->p_proc_flag & P_PR_FORK)
1532 1199 flags |= PR_FORK;
1533 1200 if (p->p_proc_flag & P_PR_RUNLCL)
1534 1201 flags |= PR_RLC;
1535 1202 if (p->p_proc_flag & P_PR_KILLCL)
1536 1203 flags |= PR_KLC;
1537 1204 if (p->p_proc_flag & P_PR_ASYNC)
1538 1205 flags |= PR_ASYNC;
1539 1206 if (p->p_proc_flag & P_PR_BPTADJ)
1540 1207 flags |= PR_BPTADJ;
1541 1208 if (p->p_proc_flag & P_PR_PTRACE)
1542 1209 flags |= PR_PTRACE;
1543 1210 if (p->p_flag & SMSACCT)
1544 1211 flags |= PR_MSACCT;
1545 1212 if (p->p_flag & SMSFORK)
1546 1213 flags |= PR_MSFORK;
1547 1214 if (p->p_flag & SVFWAIT)
1548 1215 flags |= PR_VFORKP;
1549 1216
1550 1217 if (mdb_vread(&pid, sizeof (struct pid), p->p_pgidp) != sizeof (pid)) {
1551 1218 mdb_warn("Failed to read pid from %p\n", p->p_pgidp);
1552 1219 return (-1);
1553 1220 }
1554 1221 if (pid.pid_pgorphaned)
1555 1222 flags |= PR_ORPHAN;
1556 1223 if (p->p_pidflag & CLDNOSIGCHLD)
1557 1224 flags |= PR_NOSIGCHLD;
1558 1225 if (p->p_pidflag & CLDWAITPID)
1559 1226 flags |= PR_WAITPID;
1560 1227 sp->pr_flags = flags;
1561 1228 if (VSTOPPED(t)) {
1562 1229 sp->pr_why = PR_REQUESTED;
1563 1230 sp->pr_what = 0;
1564 1231 } else {
1565 1232 sp->pr_why = t->t_whystop;
1566 1233 sp->pr_what = t->t_whatstop;
1567 1234 }
1568 1235 sp->pr_lwpid = t->t_tid;
1569 1236 sp->pr_cursig = lwp->lwp_cursig;
1570 1237 prassignset(&sp->pr_lwppend, &t->t_sig);
1571 1238 gcore_schedctl_finish_sigblock(t);
1572 1239 prassignset(&sp->pr_lwphold, &t->t_hold);
1573 1240 if (t->t_whystop == PR_FAULTED) {
1574 1241 bcopy(&lwp->lwp_siginfo,
1575 1242 &sp->pr_info, sizeof (k_siginfo_t));
1576 1243 } else if (lwp->lwp_curinfo) {
1577 1244 mdb_sigqueue_t sigq;
1578 1245
1579 1246 if (mdb_ctf_vread(&sigq, "sigqueue_t", "mdb_sigqueue_t",
1580 1247 lwp->lwp_curinfo, 0) == -1) {
1581 1248 return (-1);
1582 1249 }
1583 1250 bcopy(&sigq.sq_info, &sp->pr_info, sizeof (k_siginfo_t));
1584 1251 }
1585 1252
1586 1253 sp->pr_altstack = lwp->lwp_sigaltstack;
1587 1254 gcore_prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1588 1255 sp->pr_oldcontext = lwp->lwp_oldcontext;
1589 1256 sp->pr_ustack = lwp->lwp_ustack;
1590 1257
1591 1258 str_addr = (uintptr_t)gcore_sclass[t->t_cid].cl_name;
1592 1259 if (mdb_readstr(sp->pr_clname, sizeof (sp->pr_clname) - 1, str_addr) ==
1593 1260 -1) {
1594 1261 mdb_warn("Failed to read string from %p\n", str_addr);
1595 1262 return (-1);
1596 1263 }
1597 1264
1598 1265 /*
1599 1266 * Fetch the current instruction, if not a system process.
1600 1267 * We don't attempt this unless the lwp is stopped.
1601 1268 */
1602 1269 if ((p->p_flag & SSYS) || p->p_as == gcore_kas)
1603 1270 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1604 1271 else if (!(flags & PR_STOPPED))
1605 1272 sp->pr_flags |= PR_PCINVAL;
1606 1273 else if (!gcore_prfetchinstr(lwp, &instr))
1607 1274 sp->pr_flags |= PR_PCINVAL;
1608 1275 else
1609 1276 sp->pr_instr = instr;
1610 1277
1611 1278 if (gcore_prisstep(lwp))
1612 1279 sp->pr_flags |= PR_STEP;
1613 1280 gcore_prgetprregs(lwp, sp->pr_reg);
1614 1281 if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1615 1282 (flags & PR_VFORKP)) {
1616 1283 user_t *up;
1617 1284 auxv_t *auxp;
1618 1285 int i;
1619 1286
1620 1287 sp->pr_errno = gcore_prgetrvals(lwp, &sp->pr_rval1,
1621 1288 &sp->pr_rval2);
1622 1289 if (sp->pr_errno == 0)
1623 1290 sp->pr_errpriv = PRIV_NONE;
1624 1291 else
1625 1292 sp->pr_errpriv = lwp->lwp_badpriv;
1626 1293
1627 1294 if (t->t_sysnum == SYS_execve) {
1628 1295 up = PTOU(p);
1629 1296 sp->pr_sysarg[0] = 0;
1630 1297 sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
1631 1298 sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
1632 1299 for (i = 0, auxp = up->u_auxv;
1633 1300 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1634 1301 i++, auxp++) {
1635 1302 if (auxp->a_type == AT_SUN_EXECNAME) {
1636 1303 sp->pr_sysarg[0] =
1637 1304 (uintptr_t)auxp->a_un.a_ptr;
1638 1305 break;
1639 1306 }
1640 1307 }
1641 1308 }
1642 1309 }
1643 1310 return (0);
1644 1311 }
1645 1312
1646 1313 static int
1647 1314 gcore_lstatus_cb(mdb_proc_t *p, lwpent_t *lwent, void *data)
1648 1315 {
1649 1316 lwpstatus_t *lstatus = data;
1650 1317 uintptr_t t_addr = (uintptr_t)lwent->le_thread;
1651 1318 mdb_kthread_t kthrd;
1652 1319
1653 1320 if (t_addr == NULL) {
1654 1321 return (1);
1655 1322 }
1656 1323
1657 1324 if (mdb_ctf_vread(&kthrd, "kthread_t", "mdb_kthread_t", t_addr, 0)
1658 1325 == -1) {
1659 1326 return (-1);
1660 1327 }
1661 1328
1662 1329 return (gcore_prgetlwpstatus(p, t_addr, &kthrd, lstatus, NULL));
1663 1330 }
1664 1331
1665 1332 static prheader_t *
1666 1333 gcore_walk_lwps(mdb_proc_t *p, lwp_callback_t callback, int nlwp,
1667 1334 size_t ent_size)
1668 1335 {
1669 1336 void *ent;
1670 1337 prheader_t *php;
1671 1338 lwpdir_t *ldp;
1672 1339 lwpdir_t ld;
1673 1340 lwpent_t lwent;
1674 1341 int status;
1675 1342 int i;
1676 1343
1677 1344 php = calloc(1, sizeof (prheader_t) + nlwp * ent_size);
1678 1345 if (php == NULL) {
1679 1346 return (NULL);
1680 1347 }
1681 1348 php->pr_nent = nlwp;
1682 1349 php->pr_entsize = ent_size;
1683 1350
1684 1351 ent = php + 1;
1685 1352 for (ldp = (lwpdir_t *)p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++,
1686 1353 ldp++) {
1687 1354 if (mdb_vread(&ld, sizeof (ld), (uintptr_t)ldp) !=
1688 1355 sizeof (ld)) {
1689 1356 mdb_warn("Failed to read lwpdir_t from %p\n", ldp);
1690 1357 goto error;
1691 1358 }
1692 1359
1693 1360 if (ld.ld_entry == NULL) {
1694 1361 continue;
1695 1362 }
1696 1363
1697 1364 if (mdb_vread(&lwent, sizeof (lwent), (uintptr_t)ld.ld_entry) !=
1698 1365 sizeof (lwent)) {
1699 1366 mdb_warn("Failed to read lwpent_t from %p\n",
1700 1367 ld.ld_entry);
1701 1368 goto error;
1702 1369 }
1703 1370
1704 1371 status = callback(p, &lwent, ent);
1705 1372 if (status == -1) {
1706 1373 dprintf("lwp callback %p returned -1\n", callback);
1707 1374 goto error;
1708 1375 }
1709 1376 if (status == 1) {
1710 1377 dprintf("lwp callback %p returned 1\n", callback);
1711 1378 continue;
1712 1379 }
1713 1380
1714 1381 ent = (caddr_t)ent + ent_size;
1715 1382 }
1716 1383
1717 1384 return (php);
1718 1385
1719 1386 error:
1720 1387 free(php);
1721 1388 return (NULL);
1722 1389 }
1723 1390
1724 1391 /*
1725 1392 * Misc helper functions.
1726 1393 */
1727 1394 /*
1728 1395 * convert code/data pair into old style wait status
1729 1396 */
1730 1397 static int
1731 1398 gcore_wstat(int code, int data)
1732 1399 {
1733 1400 int stat = (data & 0377);
1734 1401
1735 1402 switch (code) {
1736 1403 case CLD_EXITED:
1737 1404 stat <<= 8;
1738 1405 break;
1739 1406 case CLD_DUMPED:
1740 1407 stat |= WCOREFLG;
1741 1408 break;
1742 1409 case CLD_KILLED:
1743 1410 break;
1744 1411 case CLD_TRAPPED:
1745 1412 case CLD_STOPPED:
1746 1413 stat <<= 8;
1747 1414 stat |= WSTOPFLG;
1748 1415 break;
1749 1416 case CLD_CONTINUED:
1750 1417 stat = WCONTFLG;
1751 1418 break;
1752 1419 default:
1753 1420 mdb_warn("wstat: bad code %d\n", code);
1754 1421 }
1755 1422 return (stat);
1756 1423 }
1757 1424
1758 1425 #if defined(__i386) || defined(__amd64)
1759 1426 static void
1760 1427 gcore_usd_to_ssd(user_desc_t *usd, struct ssd *ssd, selector_t sel)
1761 1428 {
1762 1429 ssd->bo = USEGD_GETBASE(usd);
1763 1430 ssd->ls = USEGD_GETLIMIT(usd);
1764 1431 ssd->sel = sel;
1765 1432
1766 1433 /*
1767 1434 * set type, dpl and present bits.
1768 1435 */
1769 1436 ssd->acc1 = usd->usd_type;
1770 1437 ssd->acc1 |= usd->usd_dpl << 5;
1771 1438 ssd->acc1 |= usd->usd_p << (5 + 2);
1772 1439
1773 1440 /*
1774 1441 * set avl, DB and granularity bits.
1775 1442 */
1776 1443 ssd->acc2 = usd->usd_avl;
1777 1444
1778 1445 #if defined(__amd64)
1779 1446 ssd->acc2 |= usd->usd_long << 1;
1780 1447 #else
1781 1448 ssd->acc2 |= usd->usd_reserved << 1;
1782 1449 #endif
1783 1450
1784 1451 ssd->acc2 |= usd->usd_def32 << (1 + 1);
1785 1452 ssd->acc2 |= usd->usd_gran << (1 + 1 + 1);
1786 1453 }
1787 1454 #endif
1788 1455
1789 1456 static priv_set_t *
1790 1457 gcore_priv_getset(cred_t *cr, int set)
1791 1458 {
1792 1459 if ((CR_FLAGS(cr) & PRIV_AWARE) == 0) {
1793 1460 switch (set) {
1794 1461 case PRIV_EFFECTIVE:
1795 1462 return (&CR_OEPRIV(cr));
1796 1463 case PRIV_PERMITTED:
1797 1464 return (&CR_OPPRIV(cr));
1798 1465 }
1799 1466 }
1800 1467 return (&CR_PRIVS(cr)->crprivs[set]);
1801 1468 }
1802 1469
1803 1470 static void
1804 1471 gcore_priv_getinfo(const cred_t *cr, void *buf)
1805 1472 {
1806 1473 struct priv_info_uint *ii;
1807 1474
1808 1475 ii = buf;
1809 1476 ii->val = CR_FLAGS(cr);
1810 1477 ii->info.priv_info_size = (uint32_t)sizeof (*ii);
1811 1478 ii->info.priv_info_type = PRIV_INFO_FLAGS;
1812 1479 }
1813 1480
1814 1481 static void
1815 1482 map_list_free(prmap_node_t *n)
1816 1483 {
1817 1484 prmap_node_t *next;
1818 1485
1819 1486 while (n != NULL) {
1820 1487 next = n->next;
1821 1488 mdb_free(n, sizeof (*n));
1822 1489 n = next;
1823 1490 }
1824 1491 }
1825 1492
1826 1493 /*
1827 1494 * Ops vector functions for ::gcore.
1828 1495 */
1829 1496 /*ARGSUSED*/
1830 1497 static ssize_t
1831 1498 Pread_gcore(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
1832 1499 void *data)
1833 1500 {
1834 1501 mdb_proc_t *p = data;
1835 1502 ssize_t ret;
1836 1503
1837 1504 ret = mdb_aread(buf, n, addr, (void *)p->p_as);
1838 1505 if (ret != n) {
1839 1506 dprintf("%s: addr: %p len: %llx\n", __func__, addr, n);
1840 1507 (void) memset(buf, 0, n);
1841 1508 return (n);
1842 1509 }
1843 1510
1844 1511 return (ret);
1845 1512 }
1846 1513
1847 1514 /*ARGSUSED*/
1848 1515 static ssize_t
1849 1516 Pwrite_gcore(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
1850 1517 void *data)
1851 1518 {
1852 1519 dprintf("%s: addr: %p len: %llx\n", __func__, addr, n);
1853 1520
1854 1521 return (-1);
1855 1522 }
1856 1523
1857 1524 /*ARGSUSED*/
1858 1525 static int
1859 1526 Pread_maps_gcore(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp,
1860 1527 void *data)
1861 1528 {
1862 1529 mdb_proc_t *p = data;
1863 1530 read_maps_cbarg_t cbarg;
1864 1531 prmap_node_t *n;
1865 1532 prmap_t *pmap;
1866 1533 uintptr_t segtree_addr;
1867 1534 int error;
1868 1535 int i;
1869 1536
1870 1537 cbarg.p = p;
1871 1538 cbarg.brkseg = gcore_break_seg(p);
1872 1539 cbarg.stkseg = gcore_as_segat(p->p_as, gcore_prgetstackbase(p));
1873 1540
1874 1541 (void) memset(&cbarg, 0, sizeof (cbarg));
1875 1542 segtree_addr = p->p_as + mdb_ctf_offsetof_by_name("struct as",
1876 1543 "a_segtree");
1877 1544 error = avl_walk_mdb(segtree_addr, read_maps_cb, &cbarg);
1878 1545 if (error != WALK_DONE) {
1879 1546 return (-1);
1880 1547 }
1881 1548
1882 1549 /* Conver the linked list into an array */
1883 1550 pmap = malloc(cbarg.map_len * sizeof (*pmap));
1884 1551 if (pmap == NULL) {
1885 1552 map_list_free(cbarg.map_head);
1886 1553 return (-1);
1887 1554 }
1888 1555
1889 1556 for (i = 0, n = cbarg.map_head; i < cbarg.map_len; i++, n = n->next) {
1890 1557 (void) memcpy(&pmap[i], &n->m, sizeof (prmap_t));
1891 1558 }
1892 1559 map_list_free(cbarg.map_head);
1893 1560
1894 1561 for (i = 0; i < cbarg.map_len; i++) {
1895 1562 dprintf("pr_vaddr: %p pr_size: %llx, pr_name: %s "
1896 1563 "pr_offset: %p pr_mflags: 0x%x\n",
1897 1564 pmap[i].pr_vaddr, pmap[i].pr_size,
1898 1565 pmap[i].pr_mapname, pmap[i].pr_offset,
1899 1566 pmap[i].pr_mflags);
1900 1567 }
1901 1568
1902 1569 *Pmapp = pmap;
1903 1570 *nmapp = cbarg.map_len;
1904 1571
1905 1572 return (0);
1906 1573 }
1907 1574
1908 1575 /*ARGSUSED*/
1909 1576 static void
1910 1577 Pread_aux_gcore(struct ps_prochandle *P, auxv_t **auxvp, int *nauxp, void *data)
1911 1578 {
1912 1579 mdb_proc_t *p = data;
1913 1580 auxv_t *auxv;
1914 1581 int naux;
1915 1582
1916 1583 naux = __KERN_NAUXV_IMPL;
1917 1584 auxv = calloc(naux + 1, sizeof (*auxv));
1918 1585 if (auxv == NULL) {
1919 1586 *auxvp = NULL;
1920 1587 *nauxp = 0;
1921 1588 return;
1922 1589 }
1923 1590
1924 1591 (void) memcpy(auxv, p->p_user.u_auxv, naux * sizeof (*auxv));
1925 1592
1926 1593 *auxvp = auxv;
1927 1594 *nauxp = naux;
1928 1595 }
1929 1596
1930 1597 /*ARGSUSED*/
1931 1598 static int
1932 1599 Pcred_gcore(struct ps_prochandle *P, prcred_t *prcp, int ngroups, void *data)
1933 1600 {
1934 1601 mdb_proc_t *p = data;
1935 1602 cred_t cr;
1936 1603 credgrp_t crgrp;
1937 1604 int i;
1938 1605
1939 1606 if (mdb_vread(&cr, sizeof (cr), p->p_cred) != sizeof (cr)) {
1940 1607 mdb_warn("Failed to read cred_t from %p\n", p->p_cred);
1941 1608 return (-1);
1942 1609 }
1943 1610
1944 1611 prcp->pr_euid = cr.cr_uid;
1945 1612 prcp->pr_ruid = cr.cr_ruid;
1946 1613 prcp->pr_suid = cr.cr_suid;
1947 1614 prcp->pr_egid = cr.cr_gid;
1948 1615 prcp->pr_rgid = cr.cr_rgid;
1949 1616 prcp->pr_sgid = cr.cr_sgid;
1950 1617
1951 1618 if (cr.cr_grps == 0) {
1952 1619 prcp->pr_ngroups = 0;
1953 1620 return (0);
1954 1621 }
1955 1622
1956 1623 if (mdb_vread(&crgrp, sizeof (crgrp), (uintptr_t)cr.cr_grps) !=
1957 1624 sizeof (crgrp)) {
1958 1625 mdb_warn("Failed to read credgrp_t from %p\n", cr.cr_grps);
1959 1626 return (-1);
1960 1627 }
1961 1628
1962 1629 prcp->pr_ngroups = MIN(ngroups, crgrp.crg_ngroups);
1963 1630 for (i = 0; i < prcp->pr_ngroups; i++) {
1964 1631 prcp->pr_groups[i] = crgrp.crg_groups[i];
1965 1632 }
1966 1633
1967 1634 return (0);
1968 1635 }
1969 1636
1970 1637 /*ARGSUSED*/
1971 1638 static int
1972 1639 Ppriv_gcore(struct ps_prochandle *P, prpriv_t **pprv, void *data)
1973 1640 {
1974 1641 mdb_proc_t *p = data;
1975 1642 prpriv_t *pp;
1976 1643 cred_t cr;
1977 1644 priv_set_t *psa;
1978 1645 size_t pprv_size;
1979 1646 int i;
1980 1647
1981 1648 pprv_size = sizeof (prpriv_t) + PRIV_SETBYTES - sizeof (priv_chunk_t) +
1982 1649 prinfo.priv_infosize;
1983 1650
1984 1651 pp = malloc(pprv_size);
1985 1652 if (pp == NULL) {
1986 1653 return (-1);
1987 1654 }
1988 1655
1989 1656 if (mdb_vread(&cr, sizeof (cr), p->p_cred) != sizeof (cr)) {
1990 1657 mdb_warn("Failed to read cred_t from %p\n", p->p_cred);
1991 1658 free(pp);
1992 1659 return (-1);
1993 1660 }
1994 1661
1995 1662 pp->pr_nsets = PRIV_NSET;
1996 1663 pp->pr_setsize = PRIV_SETSIZE;
1997 1664 pp->pr_infosize = prinfo.priv_infosize;
1998 1665
1999 1666 psa = (priv_set_t *)pp->pr_sets;
2000 1667 for (i = 0; i < PRIV_NSET; i++) {
2001 1668 psa[i] = *gcore_priv_getset(&cr, i);
2002 1669 }
2003 1670
2004 1671 gcore_priv_getinfo(&cr, (char *)pp + PRIV_PRPRIV_INFO_OFFSET(pp));
2005 1672
2006 1673 *pprv = pp;
2007 1674 return (0);
2008 1675 }
2009 1676
2010 1677 /*
2011 1678 * Fields not filled populated:
2012 1679 * - pr_utime
2013 1680 * - pr_stkbase
2014 1681 * - pr_cutime
2015 1682 * - pr_cstime
2016 1683 * - pr_agentid
2017 1684 */
2018 1685 /*ARGSUSED*/
2019 1686 static void
2020 1687 Pstatus_gcore(struct ps_prochandle *P, pstatus_t *sp, void *data)
2021 1688 {
2022 1689 mdb_proc_t *p = data;
2023 1690 uintptr_t t_addr;
2024 1691 mdb_kthread_t kthr;
2025 1692 mdb_kthread_t *t;
2026 1693 pcommon_t pc;
2027 1694
2028 1695 t_addr = gcore_prchoose(p);
2029 1696 if (t_addr != NULL) {
2030 1697 if (mdb_ctf_vread(&kthr, "kthread_t", "mdb_kthread_t", t_addr,
2031 1698 0) == -1) {
2032 1699 return;
2033 1700 }
2034 1701 t = &kthr;
2035 1702 }
2036 1703
2037 1704 /* just bzero the process part, prgetlwpstatus() does the rest */
2038 1705 bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t));
2039 1706
2040 1707 if (pcommon_init(p, &pc) == -1) {
2041 1708 return;
2042 1709 }
2043 1710 sp->pr_nlwp = pc.pc_nlwp;
2044 1711 sp->pr_nzomb = pc.pc_nzomb;
2045 1712 sp->pr_pid = pc.pc_pid;
2046 1713 sp->pr_ppid = pc.pc_ppid;
2047 1714 sp->pr_pgid = pc.pc_pgid;
2048 1715 sp->pr_sid = pc.pc_sid;
2049 1716 sp->pr_taskid = pc.pc_taskid;
2050 1717 sp->pr_projid = pc.pc_projid;
2051 1718 sp->pr_zoneid = pc.pc_zoneid;
2052 1719 sp->pr_dmodel = pc.pc_dmodel;
2053 1720
2054 1721 prassignset(&sp->pr_sigpend, &p->p_sig);
2055 1722 sp->pr_brkbase = p->p_brkbase;
2056 1723 sp->pr_brksize = p->p_brksize;
2057 1724 sp->pr_stkbase = gcore_prgetstackbase(p);
2058 1725 sp->pr_stksize = p->p_stksize;
2059 1726
2060 1727 prassignset(&sp->pr_sigtrace, &p->p_sigmask);
2061 1728 prassignset(&sp->pr_flttrace, &p->p_fltmask);
2062 1729 prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
2063 1730 prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
2064 1731
2065 1732 /* get the chosen lwp's status */
2066 1733 gcore_prgetlwpstatus(p, t_addr, t, &sp->pr_lwp, NULL);
2067 1734
2068 1735 /* replicate the flags */
2069 1736 sp->pr_flags = sp->pr_lwp.pr_flags;
2070 1737 }
2071 1738
2072 1739 /*
2073 1740 * Fields not populated:
2074 1741 * - pr_contract
2075 1742 * - pr_addr
2076 1743 * - pr_rtime
2077 1744 * - pr_ctime
2078 1745 * - pr_ttydev
2079 1746 * - pr_pctcpu
2080 1747 * - pr_size
2081 1748 * - pr_rsize
2082 1749 * - pr_pctmem
2083 1750 */
2084 1751 /*ARGSUSED*/
2085 1752 static const psinfo_t *
2086 1753 Ppsinfo_gcore(struct ps_prochandle *P, psinfo_t *psp, void *data)
2087 1754 {
2088 1755 mdb_proc_t *p = data;
2089 1756 mdb_kthread_t *t;
2090 1757 mdb_pool_t pool;
2091 1758 cred_t cr;
2092 1759 uintptr_t t_addr;
2093 1760 pcommon_t pc;
2094 1761
2095 1762 if ((t_addr = gcore_prchoose(p)) == NULL) {
2096 1763 bzero(psp, sizeof (*psp));
2097 1764 } else {
2098 1765 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2099 1766 }
2100 1767
2101 1768 if (pcommon_init(p, &pc) == -1) {
2102 1769 return (NULL);
2103 1770 }
2104 1771 psp->pr_nlwp = pc.pc_nlwp;
2105 1772 psp->pr_nzomb = pc.pc_nzomb;
2106 1773 psp->pr_pid = pc.pc_pid;
2107 1774 psp->pr_ppid = pc.pc_ppid;
2108 1775 psp->pr_pgid = pc.pc_pgid;
2109 1776 psp->pr_sid = pc.pc_sid;
2110 1777 psp->pr_taskid = pc.pc_taskid;
2111 1778 psp->pr_projid = pc.pc_projid;
2112 1779 psp->pr_dmodel = pc.pc_dmodel;
2113 1780
2114 1781 /*
2115 1782 * only export SSYS and SMSACCT; everything else is off-limits to
2116 1783 * userland apps.
2117 1784 */
2118 1785 psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2119 1786
2120 1787 if (mdb_vread(&cr, sizeof (cr), p->p_cred) != sizeof (cr)) {
2121 1788 mdb_warn("Failed to read cred_t from %p\n", p->p_cred);
2122 1789 return (NULL);
2123 1790 }
2124 1791
2125 1792 psp->pr_uid = cr.cr_ruid;
2126 1793 psp->pr_euid = cr.cr_uid;
2127 1794 psp->pr_gid = cr.cr_rgid;
2128 1795 psp->pr_egid = cr.cr_gid;
2129 1796
2130 1797 if (mdb_ctf_vread(&pool, "pool_t", "mdb_pool_t", p->p_pool, 0) == -1) {
2131 1798 return (NULL);
2132 1799 }
2133 1800 psp->pr_poolid = pool.pool_id;
2134 1801
2135 1802 if (t_addr == 0) {
2136 1803 int wcode = p->p_wcode;
2137 1804
2138 1805 if (wcode)
2139 1806 psp->pr_wstat = gcore_wstat(wcode, p->p_wdata);
2140 1807 psp->pr_ttydev = PRNODEV;
2141 1808 psp->pr_lwp.pr_state = SZOMB;
2142 1809 psp->pr_lwp.pr_sname = 'Z';
2143 1810 psp->pr_lwp.pr_bindpro = PBIND_NONE;
2144 1811 psp->pr_lwp.pr_bindpset = PS_NONE;
2145 1812 } else {
2146 1813 mdb_kthread_t kthr;
2147 1814 user_t *up = PTOU(p);
2148 1815
2149 1816 psp->pr_start = up->u_start;
2150 1817 bcopy(up->u_comm, psp->pr_fname,
2151 1818 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2152 1819 bcopy(up->u_psargs, psp->pr_psargs,
2153 1820 MIN(PRARGSZ-1, PSARGSZ));
2154 1821
2155 1822 psp->pr_argc = up->u_argc;
2156 1823 psp->pr_argv = up->u_argv;
2157 1824 psp->pr_envp = up->u_envp;
2158 1825
2159 1826 /* get the chosen lwp's lwpsinfo */
2160 1827 if (mdb_ctf_vread(&kthr, "kthread_t", "mdb_kthread_t", t_addr,
2161 1828 0) == -1) {
2162 1829 return (NULL);
2163 1830 }
2164 1831 t = &kthr;
2165 1832
2166 1833 gcore_prgetlwpsinfo(t_addr, t, &psp->pr_lwp);
2167 1834 }
2168 1835
2169 1836 return (NULL);
2170 1837 }
2171 1838
2172 1839 /*ARGSUSED*/
2173 1840 static prheader_t *
2174 1841 Plstatus_gcore(struct ps_prochandle *P, void *data)
2175 1842 {
2176 1843 mdb_proc_t *p = data;
2177 1844 int nlwp = p->p_lwpcnt;
2178 1845 size_t ent_size = LSPAN(lwpstatus_t);
2179 1846
2180 1847 return (gcore_walk_lwps(p, gcore_lstatus_cb, nlwp, ent_size));
2181 1848 }
2182 1849
2183 1850 /*ARGSUSED*/
2184 1851 static prheader_t *
2185 1852 Plpsinfo_gcore(struct ps_prochandle *P, void *data)
2186 1853 {
2187 1854 mdb_proc_t *p = data;
2188 1855 int nlwp = p->p_lwpcnt + p->p_zombcnt;
2189 1856 size_t ent_size = LSPAN(lwpsinfo_t);
2190 1857
2191 1858 return (gcore_walk_lwps(p, gcore_lpsinfo_cb, nlwp, ent_size));
2192 1859 }
2193 1860
2194 1861 /*ARGSUSED*/
2195 1862 static char *
2196 1863 Pplatform_gcore(struct ps_prochandle *P, char *s, size_t n, void *data)
2197 1864 {
2198 1865 char platform[SYS_NMLN];
2199 1866
2200 1867 if (mdb_readvar(platform, "platform") == -1) {
2201 1868 mdb_warn("failed to read platform!\n");
2202 1869 return (NULL);
2203 1870 }
2204 1871 dprintf("platform: %s\n", platform);
2205 1872
2206 1873 (void) strncpy(s, platform, n);
2207 1874 return (s);
2208 1875 }
2209 1876
2210 1877 /*ARGSUSED*/
2211 1878 static int
2212 1879 Puname_gcore(struct ps_prochandle *P, struct utsname *u, void *data)
2213 1880 {
2214 1881 if (mdb_readvar(u, "utsname") != sizeof (*u)) {
2215 1882 return (-1);
2216 1883 }
2217 1884
2218 1885 return (0);
2219 1886 }
2220 1887
2221 1888 /*ARGSUSED*/
2222 1889 static char *
2223 1890 Pzonename_gcore(struct ps_prochandle *P, char *s, size_t n, void *data)
2224 1891 {
2225 1892 mdb_proc_t *p = data;
2226 1893 mdb_zone_t zone;
2227 1894
2228 1895 if (mdb_ctf_vread(&zone, "zone_t", "mdb_zone_t", p->p_zone, 0) == -1) {
2229 1896 return (NULL);
2230 1897 }
2231 1898
2232 1899 if (mdb_readstr(s, n, zone.zone_name) == -1) {
2233 1900 mdb_warn("Failed to read zone name from %p\n", zone.zone_name);
2234 1901 return (NULL);
2235 1902 }
2236 1903
2237 1904 return (s);
2238 1905 }
2239 1906
2240 1907 /*ARGSUSED*/
2241 1908 static char *
2242 1909 Pexecname_gcore(struct ps_prochandle *P, char *buf, size_t buflen, void *data)
2243 1910 {
2244 1911 mdb_proc_t *p = data;
2245 1912 mdb_vnode_t vn;
2246 1913
2247 1914 if (mdb_ctf_vread(&vn, "vnode_t", "mdb_vnode_t", p->p_exec, 0) == -1) {
2248 1915 return (NULL);
2249 1916 }
2250 1917
2251 1918 if (mdb_readstr(buf, buflen, vn.v_path) == -1) {
2252 1919 mdb_warn("Failed to read vnode path from %p\n", vn.v_path);
2253 1920 return (NULL);
2254 1921 }
2255 1922
2256 1923 dprintf("execname: %s\n", buf);
2257 1924
2258 1925 return (buf);
2259 1926 }
2260 1927
2261 1928 #if defined(__i386) || defined(__amd64)
2262 1929 /*ARGSUSED*/
2263 1930 static int
2264 1931 Pldt_gcore(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
2265 1932 {
2266 1933 mdb_proc_t *p = data;
2267 1934 user_desc_t *udp;
2268 1935 user_desc_t *ldts;
2269 1936 size_t ldt_size;
2270 1937 int i, limit;
2271 1938
2272 1939 if (p->p_ldt == NULL) {
2273 1940 return (0);
2274 1941 }
2275 1942
2276 1943 limit = p->p_ldtlimit;
2277 1944
2278 1945 /* Is this call just to query the size ? */
2279 1946 if (pldt == NULL || nldt == 0) {
2280 1947 return (limit);
2281 1948 }
2282 1949
2283 1950 ldt_size = limit * sizeof (*ldts);
2284 1951 ldts = malloc(ldt_size);
2285 1952 if (ldts == NULL) {
2286 1953 mdb_warn("Failed to malloc ldts (size %lld)n", ldt_size);
2287 1954 return (-1);
2288 1955 }
2289 1956
2290 1957 if (mdb_vread(ldts, ldt_size, p->p_ldt) != ldt_size) {
2291 1958 mdb_warn("Failed to read ldts from %p\n", p->p_ldt);
2292 1959 free(ldts);
2293 1960 return (-1);
2294 1961 }
2295 1962
2296 1963 for (i = LDT_UDBASE, udp = &ldts[i]; i <= limit; i++, udp++) {
2297 1964 if (udp->usd_type != 0 || udp->usd_dpl != 0 ||
2298 1965 udp->usd_p != 0) {
2299 1966 gcore_usd_to_ssd(udp, pldt++, SEL_LDT(i));
2300 1967 }
2301 1968 }
2302 1969
2303 1970 free(ldts);
2304 1971 return (limit);
2305 1972 }
2306 1973 #endif
2307 1974
2308 1975 static const ps_ops_t Pgcore_ops = {
2309 1976 .pop_pread = Pread_gcore,
2310 1977 .pop_pwrite = Pwrite_gcore,
2311 1978 .pop_read_maps = Pread_maps_gcore,
2312 1979 .pop_read_aux = Pread_aux_gcore,
2313 1980 .pop_cred = Pcred_gcore,
2314 1981 .pop_priv = Ppriv_gcore,
2315 1982 .pop_psinfo = Ppsinfo_gcore,
2316 1983 .pop_status = Pstatus_gcore,
2317 1984 .pop_lstatus = Plstatus_gcore,
2318 1985 .pop_lpsinfo = Plpsinfo_gcore,
2319 1986 .pop_platform = Pplatform_gcore,
2320 1987 .pop_uname = Puname_gcore,
2321 1988 .pop_zonename = Pzonename_gcore,
2322 1989 .pop_execname = Pexecname_gcore,
2323 1990 #if defined(__i386) || defined(__amd64)
2324 1991 .pop_ldt = Pldt_gcore
2325 1992 #endif
2326 1993 };
2327 1994
2328 1995 /*ARGSUSED*/
2329 1996 int
2330 1997 gcore_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2331 1998 {
2332 1999 struct ps_prochandle *P;
2333 2000 char core_name[MAXNAMELEN];
2334 2001 mdb_proc_t p;
2335 2002 mdb_pid_t pid;
2336 2003 int error;
2337 2004
2338 2005 if (!gcore_initialized) {
2339 2006 mdb_warn("gcore unavailable\n");
2340 2007 return (DCMD_ERR);
2341 2008 }
2342 2009
2343 2010 if (mdb_ctf_vread(&p, "proc_t", "mdb_proc_t", addr, 0) == -1) {
2344 2011 return (DCMD_ERR);
2345 2012 }
2346 2013
2347 2014 if (p.p_flag & SSYS) {
2348 2015 mdb_warn("'%s' is a system process\n", p.p_user.u_comm);
2349 2016 return (DCMD_ERR);
2350 2017 }
2351 2018
2352 2019 if (mdb_ctf_vread(&pid, "struct pid", "mdb_pid_t", p.p_pidp, 0)
2353 2020 == -1) {
2354 2021 return (DCMD_ERR);
2355 2022 }
2356 2023
2357 2024 if ((P = Pgrab_ops(pid.pid_id, &p, &Pgcore_ops, PGRAB_INCORE)) ==
2358 2025 NULL) {
2359 2026 mdb_warn("Failed to initialize proc handle");
2360 2027 return (DCMD_ERR);
2361 2028 }
2362 2029
2363 2030 (void) snprintf(core_name, sizeof (core_name), "core.%s.%d",
2364 2031 p.p_user.u_comm, pid.pid_id);
2365 2032
2366 2033 if ((error = Pgcore(P, core_name, CC_CONTENT_DEFAULT)) != 0) {
2367 2034 mdb_warn("Failed to generate core file: %d", error);
2368 2035 Pfree(P);
2369 2036 return (DCMD_ERR);
2370 2037 }
2371 2038
2372 2039 Pfree(P);
2373 2040 mdb_printf("Created core file: %s\n", core_name);
2374 2041
2375 2042 return (0);
2376 2043 }
2377 2044
2378 2045 void
2379 2046 gcore_init(void)
2380 2047 {
2381 2048 GElf_Sym sym;
2382 2049 uintptr_t priv_info_addr;
2383 2050
2384 2051 if (mdb_lookup_by_name("segvn_ops", &sym) == -1) {
2385 2052 mdb_warn("Failed to lookup symbol 'segvn_ops'\n");
2386 2053 return;
2387 2054 }
2388 2055 gcore_segvn_ops = sym.st_value;
2389 2056
2390 2057 if (mdb_readvar(&priv_info_addr, "priv_info") == -1) {
2391 2058 mdb_warn("Failed to read variable 'priv_info'\n");
2392 2059 return;
2393 2060 }
2394 2061
2395 2062 if (mdb_vread(&prinfo, sizeof (prinfo), priv_info_addr) == -1) {
2396 2063 mdb_warn("Failed to read prinfo from %p\n", priv_info_addr);
2397 2064 return;
2398 2065 }
2399 2066
2400 2067 if (mdb_lookup_by_name("sclass", &sym) == -1) {
2401 2068 mdb_warn("Failed to lookup symbol 'segvn_ops'\n");
2402 2069 return;
2403 2070 }
2404 2071
2405 2072 gcore_sclass = mdb_zalloc(sym.st_size, UM_SLEEP);
2406 2073 if (mdb_vread(gcore_sclass, sym.st_size, sym.st_value) != sym.st_size) {
2407 2074 mdb_warn("Failed to read sclass' from %p\n", sym.st_value);
2408 2075 return;
2409 2076 }
2410 2077
2411 2078 if (mdb_lookup_by_name("kas", &sym) == -1) {
2412 2079 mdb_warn("Failed to lookup symbol 'kas'\n");
2413 2080 return;
2414 2081 }
2415 2082 gcore_kas = sym.st_value;
2416 2083
2417 2084 gcore_initialized = B_TRUE;
2418 2085 }
2419 2086
2420 2087 #endif /* _KMDB */
↓ open down ↓ |
933 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX