44 #include <sys/stack.h>
45 #include <sys/cpuvar.h>
46 #include <sys/vnode.h>
47 #include <sys/vfs.h>
48 #include <sys/flock_impl.h>
49 #include <sys/kmem_impl.h>
50 #include <sys/vmem_impl.h>
51 #include <sys/kstat.h>
52 #include <sys/dditypes.h>
53 #include <sys/ddi_impldefs.h>
54 #include <sys/sysmacros.h>
55 #include <sys/sysconf.h>
56 #include <sys/task.h>
57 #include <sys/project.h>
58 #include <sys/errorq_impl.h>
59 #include <sys/cred_impl.h>
60 #include <sys/zone.h>
61 #include <sys/panic.h>
62 #include <regex.h>
63 #include <sys/port_impl.h>
64
65 #include "avl.h"
66 #include "bio.h"
67 #include "bitset.h"
68 #include "combined.h"
69 #include "contract.h"
70 #include "cpupart_mdb.h"
71 #include "cred.h"
72 #include "ctxop.h"
73 #include "cyclic.h"
74 #include "damap.h"
75 #include "ddi_periodic.h"
76 #include "devinfo.h"
77 #include "dnlc.h"
78 #include "findstack.h"
79 #include "fm.h"
80 #include "gcore.h"
81 #include "group.h"
82 #include "irm.h"
83 #include "kgrep.h"
127 pstat2ch(uchar_t state)
128 {
129 switch (state) {
130 case SSLEEP: return ('S');
131 case SRUN: return ('R');
132 case SZOMB: return ('Z');
133 case SIDL: return ('I');
134 case SONPROC: return ('O');
135 case SSTOP: return ('T');
136 case SWAIT: return ('W');
137 default: return ('?');
138 }
139 }
140
141 #define PS_PRTTHREADS 0x1
142 #define PS_PRTLWPS 0x2
143 #define PS_PSARGS 0x4
144 #define PS_TASKS 0x8
145 #define PS_PROJECTS 0x10
146 #define PS_ZONES 0x20
147
148 static int
149 ps_threadprint(uintptr_t addr, const void *data, void *private)
150 {
151 const kthread_t *t = (const kthread_t *)data;
152 uint_t prt_flags = *((uint_t *)private);
153
154 static const mdb_bitmask_t t_state_bits[] = {
155 { "TS_FREE", UINT_MAX, TS_FREE },
156 { "TS_SLEEP", TS_SLEEP, TS_SLEEP },
157 { "TS_RUN", TS_RUN, TS_RUN },
158 { "TS_ONPROC", TS_ONPROC, TS_ONPROC },
159 { "TS_ZOMB", TS_ZOMB, TS_ZOMB },
160 { "TS_STOPPED", TS_STOPPED, TS_STOPPED },
161 { "TS_WAIT", TS_WAIT, TS_WAIT },
162 { NULL, 0, 0 }
163 };
164
165 if (prt_flags & PS_PRTTHREADS)
166 mdb_printf("\tT %?a <%b>\n", addr, t->t_state, t_state_bits);
256
257 mdb_printf("%p [pid %d]:\n", addr, pid.pid_id);
258 mdb_printf("\tp_flag: %08x <%b>\n", pr.p_flag, pr.p_flag,
259 p_flag_bits);
260 mdb_printf("\tp_pidflag: %08x <%b>\n", pr.p_pidflag, pr.p_pidflag,
261 p_pidflag_bits);
262 mdb_printf("\tp_proc_flag: %08x <%b>\n", pr.p_proc_flag, pr.p_proc_flag,
263 p_proc_flag_bits);
264
265 return (DCMD_OK);
266 }
267
268 typedef struct mdb_ps_proc {
269 char p_stat;
270 struct pid *p_pidp;
271 struct pid *p_pgidp;
272 struct cred *p_cred;
273 struct sess *p_sessp;
274 struct task *p_task;
275 struct zone *p_zone;
276 pid_t p_ppid;
277 uint_t p_flag;
278 struct {
279 char u_comm[MAXCOMLEN + 1];
280 char u_psargs[PSARGSZ];
281 } p_user;
282 } mdb_ps_proc_t;
283
284 int
285 ps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
286 {
287 uint_t prt_flags = 0;
288 mdb_ps_proc_t pr;
289 struct pid pid, pgid, sid;
290 sess_t session;
291 cred_t cred;
292 task_t tk;
293 kproject_t pj;
294 zone_t zn;
295
296 if (!(flags & DCMD_ADDRSPEC)) {
297 if (mdb_walk_dcmd("proc", "ps", argc, argv) == -1) {
298 mdb_warn("can't walk 'proc'");
299 return (DCMD_ERR);
300 }
301 return (DCMD_OK);
302 }
303
304 if (mdb_getopts(argc, argv,
305 'f', MDB_OPT_SETBITS, PS_PSARGS, &prt_flags,
306 'l', MDB_OPT_SETBITS, PS_PRTLWPS, &prt_flags,
307 'T', MDB_OPT_SETBITS, PS_TASKS, &prt_flags,
308 'P', MDB_OPT_SETBITS, PS_PROJECTS, &prt_flags,
309 'z', MDB_OPT_SETBITS, PS_ZONES, &prt_flags,
310 't', MDB_OPT_SETBITS, PS_PRTTHREADS, &prt_flags, NULL) != argc)
311 return (DCMD_USAGE);
312
313 if (DCMD_HDRSPEC(flags)) {
314 mdb_printf("%<u>%1s %6s %6s %6s %6s ",
315 "S", "PID", "PPID", "PGID", "SID");
316 if (prt_flags & PS_TASKS)
317 mdb_printf("%5s ", "TASK");
318 if (prt_flags & PS_PROJECTS)
319 mdb_printf("%5s ", "PROJ");
320 if (prt_flags & PS_ZONES)
321 mdb_printf("%5s ", "ZONE");
322 mdb_printf("%6s %10s %?s %s%</u>\n",
323 "UID", "FLAGS", "ADDR", "NAME");
324 }
325
326 if (mdb_ctf_vread(&pr, "proc_t", "mdb_ps_proc_t", addr, 0) == -1)
327 return (DCMD_ERR);
328
329 mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp);
330 mdb_vread(&pgid, sizeof (pgid), (uintptr_t)pr.p_pgidp);
331 mdb_vread(&cred, sizeof (cred), (uintptr_t)pr.p_cred);
332 mdb_vread(&session, sizeof (session), (uintptr_t)pr.p_sessp);
333 mdb_vread(&sid, sizeof (sid), (uintptr_t)session.s_sidp);
334 if (prt_flags & (PS_TASKS | PS_PROJECTS))
335 mdb_vread(&tk, sizeof (tk), (uintptr_t)pr.p_task);
336 if (prt_flags & PS_PROJECTS)
337 mdb_vread(&pj, sizeof (pj), (uintptr_t)tk.tk_proj);
338 if (prt_flags & PS_ZONES)
339 mdb_vread(&zn, sizeof (zn), (uintptr_t)pr.p_zone);
340
341 mdb_printf("%c %6d %6d %6d %6d ",
342 pstat2ch(pr.p_stat), pid.pid_id, pr.p_ppid, pgid.pid_id,
343 sid.pid_id);
344 if (prt_flags & PS_TASKS)
345 mdb_printf("%5d ", tk.tk_tkid);
346 if (prt_flags & PS_PROJECTS)
347 mdb_printf("%5d ", pj.kpj_id);
348 if (prt_flags & PS_ZONES)
349 mdb_printf("%5d ", zn.zone_id);
350 mdb_printf("%6d 0x%08x %0?p %s\n",
351 cred.cr_uid, pr.p_flag, addr,
352 (prt_flags & PS_PSARGS) ? pr.p_user.u_psargs : pr.p_user.u_comm);
353
354 if (prt_flags & ~PS_PSARGS)
355 (void) mdb_pwalk("thread", ps_threadprint, &prt_flags, addr);
356
357 return (DCMD_OK);
358 }
359
360 static void
361 ps_help(void)
362 {
363 mdb_printf("Display processes.\n\n"
364 "Options:\n"
365 " -f\tDisplay command arguments\n"
366 " -l\tDisplay LWPs\n"
367 " -T\tDisplay tasks\n"
368 " -P\tDisplay projects\n"
369 " -z\tDisplay zones\n"
370 " -t\tDisplay threads\n\n");
371
372 mdb_printf("The resulting output is a table of the processes on the "
373 "system. The\n"
374 "columns in the output consist of a combination of the "
375 "following fields:\n\n");
376 mdb_printf("S\tProcess state. Possible states are:\n"
377 "\tS\tSleeping (SSLEEP)\n"
378 "\tR\tRunnable (SRUN)\n"
379 "\tZ\tZombie (SZOMB)\n"
380 "\tI\tIdle (SIDL)\n"
381 "\tO\tOn Cpu (SONPROC)\n"
382 "\tT\tStopped (SSTOP)\n"
383 "\tW\tWaiting (SWAIT)\n");
384
385 mdb_printf("PID\tProcess id.\n");
386 mdb_printf("PPID\tParent process id.\n");
387 mdb_printf("PGID\tProcess group id.\n");
388 mdb_printf("SID\tProcess id of the session leader.\n");
389 mdb_printf("TASK\tThe task id of the process.\n");
390 mdb_printf("PROJ\tThe project id of the process.\n");
391 mdb_printf("ZONE\tThe zone id of the process.\n");
392 mdb_printf("UID\tThe user id of the process.\n");
393 mdb_printf("FLAGS\tThe process flags (see ::pflags).\n");
394 mdb_printf("ADDR\tThe kernel address of the proc_t structure of the "
395 "process\n");
396 mdb_printf("NAME\tThe name (p_user.u_comm field) of the process. If "
397 "the -f flag\n"
398 "\tis specified, the arguments of the process are displayed.\n");
399 }
400
401 #define PG_NEWEST 0x0001
402 #define PG_OLDEST 0x0002
403 #define PG_PIPE_OUT 0x0004
404 #define PG_EXACT_MATCH 0x0008
405
406 typedef struct pgrep_data {
407 uint_t pg_flags;
408 uint_t pg_psflags;
409 uintptr_t pg_xaddr;
410 hrtime_t pg_xstart;
411 const char *pg_pat;
|
44 #include <sys/stack.h>
45 #include <sys/cpuvar.h>
46 #include <sys/vnode.h>
47 #include <sys/vfs.h>
48 #include <sys/flock_impl.h>
49 #include <sys/kmem_impl.h>
50 #include <sys/vmem_impl.h>
51 #include <sys/kstat.h>
52 #include <sys/dditypes.h>
53 #include <sys/ddi_impldefs.h>
54 #include <sys/sysmacros.h>
55 #include <sys/sysconf.h>
56 #include <sys/task.h>
57 #include <sys/project.h>
58 #include <sys/errorq_impl.h>
59 #include <sys/cred_impl.h>
60 #include <sys/zone.h>
61 #include <sys/panic.h>
62 #include <regex.h>
63 #include <sys/port_impl.h>
64 #include <sys/contract/process_impl.h>
65
66 #include "avl.h"
67 #include "bio.h"
68 #include "bitset.h"
69 #include "combined.h"
70 #include "contract.h"
71 #include "cpupart_mdb.h"
72 #include "cred.h"
73 #include "ctxop.h"
74 #include "cyclic.h"
75 #include "damap.h"
76 #include "ddi_periodic.h"
77 #include "devinfo.h"
78 #include "dnlc.h"
79 #include "findstack.h"
80 #include "fm.h"
81 #include "gcore.h"
82 #include "group.h"
83 #include "irm.h"
84 #include "kgrep.h"
128 pstat2ch(uchar_t state)
129 {
130 switch (state) {
131 case SSLEEP: return ('S');
132 case SRUN: return ('R');
133 case SZOMB: return ('Z');
134 case SIDL: return ('I');
135 case SONPROC: return ('O');
136 case SSTOP: return ('T');
137 case SWAIT: return ('W');
138 default: return ('?');
139 }
140 }
141
142 #define PS_PRTTHREADS 0x1
143 #define PS_PRTLWPS 0x2
144 #define PS_PSARGS 0x4
145 #define PS_TASKS 0x8
146 #define PS_PROJECTS 0x10
147 #define PS_ZONES 0x20
148 #define PS_SERVICES 0x40
149
150 static int
151 ps_threadprint(uintptr_t addr, const void *data, void *private)
152 {
153 const kthread_t *t = (const kthread_t *)data;
154 uint_t prt_flags = *((uint_t *)private);
155
156 static const mdb_bitmask_t t_state_bits[] = {
157 { "TS_FREE", UINT_MAX, TS_FREE },
158 { "TS_SLEEP", TS_SLEEP, TS_SLEEP },
159 { "TS_RUN", TS_RUN, TS_RUN },
160 { "TS_ONPROC", TS_ONPROC, TS_ONPROC },
161 { "TS_ZOMB", TS_ZOMB, TS_ZOMB },
162 { "TS_STOPPED", TS_STOPPED, TS_STOPPED },
163 { "TS_WAIT", TS_WAIT, TS_WAIT },
164 { NULL, 0, 0 }
165 };
166
167 if (prt_flags & PS_PRTTHREADS)
168 mdb_printf("\tT %?a <%b>\n", addr, t->t_state, t_state_bits);
258
259 mdb_printf("%p [pid %d]:\n", addr, pid.pid_id);
260 mdb_printf("\tp_flag: %08x <%b>\n", pr.p_flag, pr.p_flag,
261 p_flag_bits);
262 mdb_printf("\tp_pidflag: %08x <%b>\n", pr.p_pidflag, pr.p_pidflag,
263 p_pidflag_bits);
264 mdb_printf("\tp_proc_flag: %08x <%b>\n", pr.p_proc_flag, pr.p_proc_flag,
265 p_proc_flag_bits);
266
267 return (DCMD_OK);
268 }
269
270 typedef struct mdb_ps_proc {
271 char p_stat;
272 struct pid *p_pidp;
273 struct pid *p_pgidp;
274 struct cred *p_cred;
275 struct sess *p_sessp;
276 struct task *p_task;
277 struct zone *p_zone;
278 struct cont_process *p_ct_process;
279 pid_t p_ppid;
280 uint_t p_flag;
281 struct {
282 char u_comm[MAXCOMLEN + 1];
283 char u_psargs[PSARGSZ];
284 } p_user;
285 } mdb_ps_proc_t;
286
287 /*
288 * A reasonable enough limit. Note that we purposefully let this column over-run
289 * if needed.
290 */
291 #define FMRI_LEN (128)
292
293 int
294 ps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
295 {
296 uint_t prt_flags = 0;
297 mdb_ps_proc_t pr;
298 struct pid pid, pgid, sid;
299 sess_t session;
300 cred_t cred;
301 task_t tk;
302 kproject_t pj;
303 zone_t zn;
304 struct cont_process cp;
305 char fmri[FMRI_LEN] = "";
306
307 if (!(flags & DCMD_ADDRSPEC)) {
308 if (mdb_walk_dcmd("proc", "ps", argc, argv) == -1) {
309 mdb_warn("can't walk 'proc'");
310 return (DCMD_ERR);
311 }
312 return (DCMD_OK);
313 }
314
315 if (mdb_getopts(argc, argv,
316 'f', MDB_OPT_SETBITS, PS_PSARGS, &prt_flags,
317 'l', MDB_OPT_SETBITS, PS_PRTLWPS, &prt_flags,
318 's', MDB_OPT_SETBITS, PS_SERVICES, &prt_flags,
319 'T', MDB_OPT_SETBITS, PS_TASKS, &prt_flags,
320 'P', MDB_OPT_SETBITS, PS_PROJECTS, &prt_flags,
321 'z', MDB_OPT_SETBITS, PS_ZONES, &prt_flags,
322 't', MDB_OPT_SETBITS, PS_PRTTHREADS, &prt_flags, NULL) != argc)
323 return (DCMD_USAGE);
324
325 if (DCMD_HDRSPEC(flags)) {
326 mdb_printf("%<u>%-1s %-6s %-6s %-6s %-6s ",
327 "S", "PID", "PPID", "PGID", "SID");
328 if (prt_flags & PS_TASKS)
329 mdb_printf("%-5s ", "TASK");
330 if (prt_flags & PS_PROJECTS)
331 mdb_printf("%-5s ", "PROJ");
332 if (prt_flags & PS_ZONES)
333 mdb_printf("%-5s ", "ZONE");
334 if (prt_flags & PS_SERVICES)
335 mdb_printf("%-40s ", "SERVICE");
336 mdb_printf("%-6s %-10s %-?s %-s%</u>\n",
337 "UID", "FLAGS", "ADDR", "NAME");
338 }
339
340 if (mdb_ctf_vread(&pr, "proc_t", "mdb_ps_proc_t", addr, 0) == -1)
341 return (DCMD_ERR);
342
343 mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp);
344 mdb_vread(&pgid, sizeof (pgid), (uintptr_t)pr.p_pgidp);
345 mdb_vread(&cred, sizeof (cred), (uintptr_t)pr.p_cred);
346 mdb_vread(&session, sizeof (session), (uintptr_t)pr.p_sessp);
347 mdb_vread(&sid, sizeof (sid), (uintptr_t)session.s_sidp);
348 if (prt_flags & (PS_TASKS | PS_PROJECTS))
349 mdb_vread(&tk, sizeof (tk), (uintptr_t)pr.p_task);
350 if (prt_flags & PS_PROJECTS)
351 mdb_vread(&pj, sizeof (pj), (uintptr_t)tk.tk_proj);
352 if (prt_flags & PS_ZONES)
353 mdb_vread(&zn, sizeof (zn), (uintptr_t)pr.p_zone);
354 if ((prt_flags & PS_SERVICES) && pr.p_ct_process != NULL) {
355 mdb_vread(&cp, sizeof (cp), (uintptr_t)pr.p_ct_process);
356
357 if (mdb_read_refstr((uintptr_t)cp.conp_svc_fmri, fmri,
358 sizeof (fmri)) <= 0)
359 (void) strlcpy(fmri, "?", sizeof (fmri));
360
361 /* Strip any standard prefix and suffix. */
362 if (strncmp(fmri, "svc:/", sizeof ("svc:/") - 1) == 0) {
363 char *i = fmri;
364 char *j = fmri + sizeof ("svc:/") - 1;
365 for (; *j != '\0'; i++, j++) {
366 if (strcmp(j, ":default") == 0)
367 break;
368 *i = *j;
369 }
370
371 *i = '\0';
372 }
373 }
374
375 mdb_printf("%-c %-6d %-6d %-6d %-6d ",
376 pstat2ch(pr.p_stat), pid.pid_id, pr.p_ppid, pgid.pid_id,
377 sid.pid_id);
378 if (prt_flags & PS_TASKS)
379 mdb_printf("%-5d ", tk.tk_tkid);
380 if (prt_flags & PS_PROJECTS)
381 mdb_printf("%-5d ", pj.kpj_id);
382 if (prt_flags & PS_ZONES)
383 mdb_printf("%-5d ", zn.zone_id);
384 if (prt_flags & PS_SERVICES)
385 mdb_printf("%-40s ", fmri);
386 mdb_printf("%-6d 0x%08x %0?p %-s\n",
387 cred.cr_uid, pr.p_flag, addr,
388 (prt_flags & PS_PSARGS) ? pr.p_user.u_psargs : pr.p_user.u_comm);
389
390 if (prt_flags & ~PS_PSARGS)
391 (void) mdb_pwalk("thread", ps_threadprint, &prt_flags, addr);
392
393 return (DCMD_OK);
394 }
395
396 static void
397 ps_help(void)
398 {
399 mdb_printf("Display processes.\n\n"
400 "Options:\n"
401 " -f\tDisplay command arguments\n"
402 " -l\tDisplay LWPs\n"
403 " -T\tDisplay tasks\n"
404 " -P\tDisplay projects\n"
405 " -s\tDisplay SMF FMRI\n"
406 " -z\tDisplay zones\n"
407 " -t\tDisplay threads\n\n");
408
409 mdb_printf("The resulting output is a table of the processes on the "
410 "system. The\n"
411 "columns in the output consist of a combination of the "
412 "following fields:\n\n");
413 mdb_printf("S\tProcess state. Possible states are:\n"
414 "\tS\tSleeping (SSLEEP)\n"
415 "\tR\tRunnable (SRUN)\n"
416 "\tZ\tZombie (SZOMB)\n"
417 "\tI\tIdle (SIDL)\n"
418 "\tO\tOn Cpu (SONPROC)\n"
419 "\tT\tStopped (SSTOP)\n"
420 "\tW\tWaiting (SWAIT)\n");
421
422 mdb_printf("PID\tProcess id.\n");
423 mdb_printf("PPID\tParent process id.\n");
424 mdb_printf("PGID\tProcess group id.\n");
425 mdb_printf("SID\tProcess id of the session leader.\n");
426 mdb_printf("TASK\tThe task id of the process.\n");
427 mdb_printf("PROJ\tThe project id of the process.\n");
428 mdb_printf("ZONE\tThe zone id of the process.\n");
429 mdb_printf("SERVICE The SMF service FMRI of the process.\n");
430 mdb_printf("UID\tThe user id of the process.\n");
431 mdb_printf("FLAGS\tThe process flags (see ::pflags).\n");
432 mdb_printf("ADDR\tThe kernel address of the proc_t structure of the "
433 "process\n");
434 mdb_printf("NAME\tThe name (p_user.u_comm field) of the process. If "
435 "the -f flag\n"
436 "\tis specified, the arguments of the process are displayed.\n");
437 }
438
439 #define PG_NEWEST 0x0001
440 #define PG_OLDEST 0x0002
441 #define PG_PIPE_OUT 0x0004
442 #define PG_EXACT_MATCH 0x0008
443
444 typedef struct pgrep_data {
445 uint_t pg_flags;
446 uint_t pg_psflags;
447 uintptr_t pg_xaddr;
448 hrtime_t pg_xstart;
449 const char *pg_pat;
|