xref: /illumos-gate/usr/src/cmd/ptools/pstack/pstack.c (revision 241c90a0)
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  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Copyright 2018 Joyent, Inc.
26  */
27 
28 #include <sys/isa_defs.h>
29 
30 #include <stdio.h>
31 #include <stdio_ext.h>
32 #include <fcntl.h>
33 #include <ctype.h>
34 #include <string.h>
35 #include <signal.h>
36 #include <dirent.h>
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 #include <unistd.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/stack.h>
44 #include <link.h>
45 #include <limits.h>
46 #include <libelf.h>
47 #include <thread_db.h>
48 #include <libproc.h>
49 #include <setjmp.h>
50 
51 static	char	*command;
52 static	int	Fflag;
53 static	int	is64;
54 static	GElf_Sym sigh;
55 
56 /*
57  * To keep the list of user-level threads for a multithreaded process.
58  */
59 struct threadinfo {
60 	struct threadinfo *next;
61 	id_t	threadid;
62 	id_t	lwpid;
63 	td_thr_state_e state;
64 	uintptr_t startfunc;
65 	uintptr_t exitval;
66 	prgregset_t regs;
67 };
68 
69 static struct threadinfo *thr_head, *thr_tail;
70 
71 #define	TRUE	1
72 #define	FALSE	0
73 
74 #define	MAX_ARGS	8
75 
76 /*
77  * To support debugging java programs, we display java frames within a stack.
78  * The logic to walk the java frames is contained in libjvm_db.so, which is
79  * found in the same directory as libjvm.so, linked with the program.  If we are
80  * debugging a 32-bit app with a 64-binary, then the debugging library is found
81  * in the '64' subdirectory.  If we find libjvm_db.so, then we fill in these
82  * stub routines.
83  */
84 typedef struct jvm_agent jvm_agent_t;
85 typedef int java_stack_f(void *, prgregset_t, const char *, int, int, void *);
86 
87 /*
88  * The j_agent_create function takes a version parameter.  This ensures that the
89  * interface can evolve appropriately.
90  */
91 #define	JVM_DB_VERSION	1
92 static void *libjvm;
93 typedef jvm_agent_t *(*j_agent_create_f)(struct ps_prochandle *, int);
94 typedef void (*j_agent_destroy_f)(jvm_agent_t *);
95 typedef int (*j_frame_iter_f)(jvm_agent_t *, prgregset_t, java_stack_f *,
96     void *);
97 
98 static j_agent_create_f j_agent_create;
99 static j_agent_destroy_f j_agent_destroy;
100 static j_frame_iter_f j_frame_iter;
101 
102 static jvm_agent_t *load_libjvm(struct ps_prochandle *P);
103 static void reset_libjvm(jvm_agent_t *);
104 
105 /*
106  * Similar to what's done for debugging java programs, here are prototypes for
107  * the library that allows us to debug Python programs.
108  */
109 #define	PYDB_VERSION	1
110 static void *libpython;
111 
112 typedef struct pydb_agent pydb_agent_t;
113 
114 typedef pydb_agent_t *(*pydb_agent_create_f)(struct ps_prochandle *P, int vers);
115 typedef void (*pydb_agent_destroy_f)(pydb_agent_t *py);
116 typedef int (*pydb_pc_frameinfo_f)(pydb_agent_t *py, uintptr_t pc,
117     uintptr_t frame_addr, char *fbuf, size_t bufsz);
118 
119 static pydb_agent_create_f pydb_agent_create;
120 static pydb_agent_destroy_f pydb_agent_destroy;
121 static pydb_pc_frameinfo_f pydb_pc_frameinfo;
122 
123 static pydb_agent_t *load_libpython(struct ps_prochandle *P);
124 static void reset_libpython(pydb_agent_t *);
125 /*
126  * Since we must maintain both a proc handle and a jvm handle, this structure
127  * is the basic type that gets passed around.
128  */
129 typedef struct pstack_handle {
130 	struct ps_prochandle *proc;
131 	jvm_agent_t *jvm;
132 	int ignore_frame;
133 	const char *lwps;
134 	int count;
135 	pydb_agent_t *pydb;
136 } pstack_handle_t;
137 
138 static	int	thr_stack(const td_thrhandle_t *, void *);
139 static	void	free_threadinfo(void);
140 static	struct threadinfo *find_thread(id_t);
141 static	int	all_call_stacks(pstack_handle_t *, int);
142 static	void	tlhead(id_t, id_t, const char *);
143 static	int	print_frame(void *, prgregset_t, uint_t, const long *);
144 static	void	print_zombie(struct ps_prochandle *, struct threadinfo *);
145 static	void	print_syscall(const lwpstatus_t *, prgregset_t);
146 static	void	call_stack(pstack_handle_t *, const lwpstatus_t *);
147 
148 /*
149  * The number of active and zombie threads.
150  */
151 static	int	nthreads;
152 
153 int
154 main(int argc, char **argv)
155 {
156 	int retc = 0;
157 	int opt;
158 	int errflg = FALSE;
159 	core_content_t content = CC_CONTENT_DATA | CC_CONTENT_ANON |
160 	    CC_CONTENT_STACK;
161 	struct rlimit rlim;
162 
163 	if ((command = strrchr(argv[0], '/')) != NULL)
164 		command++;
165 	else
166 		command = argv[0];
167 
168 	/* options */
169 	while ((opt = getopt(argc, argv, "F")) != EOF) {
170 		switch (opt) {
171 		case 'F':
172 			/*
173 			 * If the user specifies the force option, we'll
174 			 * consent to printing out other threads' stacks
175 			 * even if the main stack is absent.
176 			 */
177 			content &= ~CC_CONTENT_STACK;
178 			Fflag = PGRAB_FORCE;
179 			break;
180 		default:
181 			errflg = TRUE;
182 			break;
183 		}
184 	}
185 
186 	argc -= optind;
187 	argv += optind;
188 
189 	if (errflg || argc <= 0) {
190 		(void) fprintf(stderr,
191 		    "usage:\t%s [-F] { pid | core }[/lwps] ...\n", command);
192 		(void) fprintf(stderr, "  (show process call stack)\n");
193 		(void) fprintf(stderr,
194 		    "  -F: force grabbing of the target process\n");
195 		exit(2);
196 	}
197 
198 	/*
199 	 * Make sure we'll have enough file descriptors to handle a target
200 	 * that has many many mappings.
201 	 */
202 	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
203 		rlim.rlim_cur = rlim.rlim_max;
204 		(void) setrlimit(RLIMIT_NOFILE, &rlim);
205 		(void) enable_extended_FILE_stdio(-1, -1);
206 	}
207 
208 	(void) proc_initstdio();
209 
210 	while (--argc >= 0) {
211 		int gcode;
212 		psinfo_t psinfo;
213 		const psinfo_t *tpsinfo;
214 		struct ps_prochandle *Pr = NULL;
215 		td_thragent_t *Tap;
216 		int threaded;
217 		pstack_handle_t handle;
218 		const char *lwps, *arg;
219 
220 		(void) proc_flushstdio();
221 
222 		arg = *argv++;
223 
224 		if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_ANY,
225 		    Fflag, &gcode, &lwps)) == NULL) {
226 			(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
227 			    command, arg, Pgrab_error(gcode));
228 			retc++;
229 			continue;
230 		}
231 
232 		if ((tpsinfo = Ppsinfo(Pr)) == NULL) {
233 			(void) fprintf(stderr, "%s: cannot examine %s: "
234 			    "lost control of process\n", command, arg);
235 			Prelease(Pr, 0);
236 			retc++;
237 			continue;
238 		}
239 		(void) memcpy(&psinfo, tpsinfo, sizeof (psinfo_t));
240 		proc_unctrl_psinfo(&psinfo);
241 
242 		if (Pstate(Pr) == PS_DEAD) {
243 			if ((Pcontent(Pr) & content) != content) {
244 				(void) fprintf(stderr, "%s: core '%s' has "
245 				    "insufficient content\n", command, arg);
246 				retc++;
247 				continue;
248 			}
249 			(void) printf("core '%s' of %d:\t%.70s\n",
250 			    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
251 		} else {
252 			(void) printf("%d:\t%.70s\n",
253 			    (int)psinfo.pr_pid, psinfo.pr_psargs);
254 		}
255 
256 		is64 = (psinfo.pr_dmodel == PR_MODEL_LP64);
257 
258 		if (Pgetauxval(Pr, AT_BASE) != -1L && Prd_agent(Pr) == NULL) {
259 			(void) fprintf(stderr, "%s: warning: librtld_db failed "
260 			    "to initialize; symbols from shared libraries will "
261 			    "not be available\n", command);
262 		}
263 
264 		/*
265 		 * First we need to get a thread agent handle.
266 		 */
267 		if (td_init() != TD_OK ||
268 		    td_ta_new(Pr, &Tap) != TD_OK)	/* no libc */
269 			threaded = FALSE;
270 		else {
271 			/*
272 			 * Iterate over all threads, calling:
273 			 *   thr_stack(td_thrhandle_t *Thp, NULL);
274 			 * for each one to generate the list of threads.
275 			 */
276 			nthreads = 0;
277 			(void) td_ta_thr_iter(Tap, thr_stack, NULL,
278 			    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
279 			    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
280 
281 			(void) td_ta_delete(Tap);
282 			threaded = TRUE;
283 		}
284 
285 		handle.proc = Pr;
286 		handle.jvm = load_libjvm(Pr);
287 		handle.pydb = load_libpython(Pr);
288 		handle.lwps = lwps;
289 		handle.count = 0;
290 
291 		if (all_call_stacks(&handle, threaded) != 0)
292 			retc++;
293 		if (threaded)
294 			free_threadinfo();
295 
296 		reset_libjvm(handle.jvm);
297 		reset_libpython(handle.pydb);
298 		Prelease(Pr, 0);
299 
300 		if (handle.count == 0)
301 			(void) fprintf(stderr, "%s: no matching LWPs found\n",
302 			    command);
303 	}
304 
305 	(void) proc_finistdio();
306 
307 	return (retc);
308 }
309 
310 /*
311  * Thread iteration call-back function.
312  * Called once for each user-level thread.
313  * Used to build the list of all threads.
314  */
315 /* ARGSUSED1 */
316 static int
317 thr_stack(const td_thrhandle_t *Thp, void *cd)
318 {
319 	td_thrinfo_t thrinfo;
320 	struct threadinfo *tip;
321 	td_err_e error;
322 
323 	if (td_thr_get_info(Thp, &thrinfo) != TD_OK)
324 		return (0);
325 
326 	tip = malloc(sizeof (struct threadinfo));
327 	tip->next = NULL;
328 	tip->threadid = thrinfo.ti_tid;
329 	tip->lwpid = thrinfo.ti_lid;
330 	tip->state = thrinfo.ti_state;
331 	tip->startfunc = thrinfo.ti_startfunc;
332 	tip->exitval = (uintptr_t)thrinfo.ti_exitval;
333 	nthreads++;
334 
335 	if (thrinfo.ti_state == TD_THR_ZOMBIE ||
336 	    ((error = td_thr_getgregs(Thp, tip->regs)) != TD_OK &&
337 	    error != TD_PARTIALREG))
338 		(void) memset(tip->regs, 0, sizeof (prgregset_t));
339 
340 	if (thr_tail)
341 		thr_tail->next = tip;
342 	else
343 		thr_head = tip;
344 	thr_tail = tip;
345 
346 	return (0);
347 }
348 
349 static void
350 free_threadinfo()
351 {
352 	struct threadinfo *tip = thr_head;
353 	struct threadinfo *next;
354 
355 	while (tip) {
356 		next = tip->next;
357 		free(tip);
358 		tip = next;
359 	}
360 
361 	thr_head = thr_tail = NULL;
362 }
363 
364 /*
365  * Find and eliminate the thread corresponding to the given lwpid.
366  */
367 static struct threadinfo *
368 find_thread(id_t lwpid)
369 {
370 	struct threadinfo *tip;
371 
372 	for (tip = thr_head; tip; tip = tip->next) {
373 		if (lwpid == tip->lwpid) {
374 			tip->lwpid = 0;
375 			return (tip);
376 		}
377 	}
378 	return (NULL);
379 }
380 
381 static int
382 thread_call_stack(void *data, const lwpstatus_t *psp,
383     const lwpsinfo_t *pip)
384 {
385 	char lwpname[THREAD_NAME_MAX] = "";
386 	pstack_handle_t *h = data;
387 	lwpstatus_t lwpstatus;
388 	struct threadinfo *tip;
389 
390 	if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid))
391 		return (0);
392 	h->count++;
393 
394 	if ((tip = find_thread(pip->pr_lwpid)) == NULL)
395 		return (0);
396 
397 	(void) Plwp_getname(h->proc, pip->pr_lwpid,
398 	    lwpname, sizeof (lwpname));
399 
400 	tlhead(tip->threadid, pip->pr_lwpid, lwpname);
401 	tip->threadid = 0;	/* finish eliminating tid */
402 	if (psp)
403 		call_stack(h, psp);
404 	else {
405 		if (tip->state == TD_THR_ZOMBIE)
406 			print_zombie(h->proc, tip);
407 		else {
408 			(void) memset(&lwpstatus, 0, sizeof (lwpstatus));
409 			(void) memcpy(lwpstatus.pr_reg, tip->regs,
410 			    sizeof (prgregset_t));
411 			call_stack(h, &lwpstatus);
412 		}
413 	}
414 	return (0);
415 }
416 
417 static int
418 lwp_call_stack(void *data,
419     const lwpstatus_t *psp, const lwpsinfo_t *pip)
420 {
421 	char lwpname[THREAD_NAME_MAX] = "";
422 	pstack_handle_t *h = data;
423 
424 	if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid))
425 		return (0);
426 	h->count++;
427 
428 	(void) Plwp_getname(h->proc, pip->pr_lwpid,
429 	    lwpname, sizeof (lwpname));
430 
431 	tlhead(0, pip->pr_lwpid, lwpname);
432 	if (psp)
433 		call_stack(h, psp);
434 	else
435 		(void) printf("\t** zombie "
436 		    "(exited, not detached, not yet joined) **\n");
437 	return (0);
438 }
439 
440 static int
441 all_call_stacks(pstack_handle_t *h, int dothreads)
442 {
443 	struct ps_prochandle *Pr = h->proc;
444 	pstatus_t status = *Pstatus(Pr);
445 
446 	(void) memset(&sigh, 0, sizeof (GElf_Sym));
447 	(void) Plookup_by_name(Pr, "libc.so", "sigacthandler", &sigh);
448 
449 	if ((status.pr_nlwp + status.pr_nzomb) <= 1 &&
450 	    !(dothreads && nthreads > 1)) {
451 		if (proc_lwp_in_set(h->lwps, status.pr_lwp.pr_lwpid)) {
452 			call_stack(h, &status.pr_lwp);
453 			h->count++;
454 		}
455 	} else {
456 		lwpstatus_t lwpstatus;
457 		struct threadinfo *tip;
458 		id_t tid;
459 
460 		if (dothreads)
461 			(void) Plwp_iter_all(Pr, thread_call_stack, h);
462 		else
463 			(void) Plwp_iter_all(Pr, lwp_call_stack, h);
464 
465 		/* for each remaining thread w/o an lwp */
466 		(void) memset(&lwpstatus, 0, sizeof (lwpstatus));
467 		for (tip = thr_head; tip; tip = tip->next) {
468 
469 			if (!proc_lwp_in_set(h->lwps, tip->lwpid))
470 				tip->threadid = 0;
471 
472 			if ((tid = tip->threadid) != 0) {
473 				(void) memcpy(lwpstatus.pr_reg, tip->regs,
474 				    sizeof (prgregset_t));
475 				tlhead(tid, tip->lwpid, NULL);
476 				if (tip->state == TD_THR_ZOMBIE)
477 					print_zombie(Pr, tip);
478 				else
479 					call_stack(h, &lwpstatus);
480 			}
481 			tip->threadid = 0;
482 			tip->lwpid = 0;
483 		}
484 	}
485 	return (0);
486 }
487 
488 /* The width of the header */
489 #define	HEAD_WIDTH	(62)
490 static void
491 tlhead(id_t threadid, id_t lwpid, const char *name)
492 {
493 	char buf[128] = { 0 };
494 	char num[16];
495 	ssize_t amt = 0;
496 	int i;
497 
498 	if (threadid == 0 && lwpid == 0)
499 		return;
500 
501 	if (lwpid > 0) {
502 		(void) snprintf(num, sizeof (num), "%d", (int)lwpid);
503 		(void) strlcat(buf, "thread# ", sizeof (buf));
504 		(void) strlcat(buf, num, sizeof (buf));
505 	}
506 
507 	if (threadid > 0) {
508 		(void) snprintf(num, sizeof (num), "%d", (int)threadid);
509 		if (lwpid > 0)
510 			(void) strlcat(buf, " / ", sizeof (buf));
511 		(void) strlcat(buf, "lwp# ", sizeof (buf));
512 		(void) strlcat(buf, num, sizeof (buf));
513 	}
514 
515 	if (name != NULL && strlen(name) > 0) {
516 		(void) strlcat(buf, " [", sizeof (buf));
517 		(void) strlcat(buf, name, sizeof (buf));
518 		(void) strlcat(buf, "]", sizeof (buf));
519 	}
520 
521 	amt = (HEAD_WIDTH - strlen(buf) - 2);
522 	if (amt < 4)
523 		amt = 4;
524 
525 	for (i = 0; i < amt / 2; i++)
526 		(void) putc('-', stdout);
527 	(void) printf(" %s ", buf);
528 	for (i = 0; i < (amt / 2) + (amt % 2); i++)
529 		(void) putc('-', stdout);
530 	(void) putc('\n', stdout);
531 }
532 
533 /*ARGSUSED*/
534 static int
535 print_java_frame(void *cld, prgregset_t gregs, const char *name, int bci,
536     int line, void *handle)
537 {
538 	int length = (is64 ? 16 : 8);
539 
540 	(void) printf(" %.*lx * %s", length, (long)gregs[R_PC], name);
541 
542 	if (bci != -1) {
543 		(void) printf("+%d", bci);
544 		if (line)
545 			(void) printf(" (line %d)", line);
546 	}
547 	(void) printf("\n");
548 
549 	return (0);
550 }
551 
552 static sigjmp_buf jumpbuf;
553 
554 /*ARGSUSED*/
555 static void
556 fatal_signal(int signo)
557 {
558 	siglongjmp(jumpbuf, 1);
559 }
560 
561 static int
562 print_frame(void *cd, prgregset_t gregs, uint_t argc, const long *argv)
563 {
564 	pstack_handle_t *h = cd;
565 	struct ps_prochandle *Pr = h->proc;
566 	uintptr_t pc = gregs[R_PC];
567 	char buff[255];
568 	GElf_Sym sym;
569 	uintptr_t start;
570 	int length = (is64? 16 : 8);
571 	int i;
572 
573 	/*
574 	 * If we are in a system call, we display the entry frame in a more
575 	 * readable manner, using the name of the system call.  In this case, we
576 	 * want to ignore this first frame, since we already displayed it
577 	 * separately.
578 	 */
579 	if (h->ignore_frame) {
580 		h->ignore_frame = 0;
581 		return (0);
582 	}
583 
584 	(void) sprintf(buff, "%.*lx", length, (long)pc);
585 	(void) strcpy(buff + length, " ????????");
586 	if (Plookup_by_addr(Pr, pc,
587 	    buff + 1 + length, sizeof (buff) - 1 - length, &sym) == 0) {
588 		start = sym.st_value;
589 	} else if (h->jvm != NULL) {
590 		int ret;
591 		void (*segv)(int), (*bus)(int), (*ill)(int);
592 
593 		segv = signal(SIGSEGV, fatal_signal);
594 		bus = signal(SIGBUS, fatal_signal);
595 		ill = signal(SIGILL, fatal_signal);
596 
597 		/* Insure against a bad libjvm_db */
598 		if (sigsetjmp(jumpbuf, 0) == 0)
599 			ret = j_frame_iter(h->jvm, gregs, print_java_frame,
600 			    NULL);
601 		else
602 			ret = -1;
603 
604 		(void) signal(SIGSEGV, segv);
605 		(void) signal(SIGBUS, bus);
606 		(void) signal(SIGILL, ill);
607 
608 		if (ret == 0)
609 			return (ret);
610 	} else {
611 		start = pc;
612 	}
613 
614 	(void) printf(" %-17s (", buff);
615 	for (i = 0; i < argc && i < MAX_ARGS; i++)
616 		(void) printf((i+1 == argc) ? "%lx" : "%lx, ", argv[i]);
617 	if (i != argc)
618 		(void) printf("...");
619 	(void) printf((start != pc) ? ") + %lx\n" : ")\n", (long)(pc - start));
620 
621 	if (h->pydb != NULL && argc > 0) {
622 		char buf_py[1024];
623 		int rc;
624 
625 		rc = pydb_pc_frameinfo(h->pydb, pc, argv[0], buf_py,
626 		    sizeof (buf_py));
627 		if (rc == 0) {
628 			(void) printf("   %s", buf_py);
629 		}
630 	}
631 
632 	/*
633 	 * If the frame's pc is in the "sigh" (a.k.a. signal handler, signal
634 	 * hack, or *sigh* ...) range, then we're about to cross a signal
635 	 * frame.  The signal number is the first argument to this function.
636 	 */
637 	if (pc - sigh.st_value < sigh.st_size) {
638 		if (sig2str((int)argv[0], buff) == -1)
639 			(void) strcpy(buff, " Unknown");
640 		(void) printf(" --- called from signal handler with "
641 		    "signal %d (SIG%s) ---\n", (int)argv[0], buff);
642 	}
643 
644 	return (0);
645 }
646 
647 static void
648 print_zombie(struct ps_prochandle *Pr, struct threadinfo *tip)
649 {
650 	char buff[255];
651 	GElf_Sym sym;
652 	uintptr_t start;
653 	int length = (is64? 16 : 8);
654 
655 	(void) sprintf(buff, "%.*lx", length, (long)tip->startfunc);
656 	(void) strcpy(buff + length, " ????????");
657 	if (Plookup_by_addr(Pr, tip->startfunc,
658 	    buff + 1 + length, sizeof (buff) - 1 - length, &sym) == 0)
659 		start = sym.st_value;
660 	else
661 		start = tip->startfunc;
662 	(void) printf(" %s()", buff);
663 	if (start != tip->startfunc)	/* doesn't happen? */
664 		(void) printf("+%lx", (long)(tip->startfunc - start));
665 	(void) printf(", exit value = 0x%.*lx\n", length, (long)tip->exitval);
666 	(void) printf("\t** zombie "
667 	    "(exited, not detached, not yet joined) **\n");
668 }
669 
670 static void
671 print_syscall(const lwpstatus_t *psp, prgregset_t reg)
672 {
673 	char sname[32];
674 	int length = (is64? 16 : 8);
675 	uint_t i;
676 
677 	(void) proc_sysname(psp->pr_syscall, sname, sizeof (sname));
678 	(void) printf(" %.*lx %-8s (", length, (long)reg[R_PC], sname);
679 	for (i = 0; i < psp->pr_nsysarg; i++)
680 		(void) printf((i+1 == psp->pr_nsysarg)? "%lx" : "%lx, ",
681 		    (long)psp->pr_sysarg[i]);
682 	(void) printf(")\n");
683 }
684 
685 static void
686 call_stack(pstack_handle_t *h, const lwpstatus_t *psp)
687 {
688 	prgregset_t reg;
689 
690 	(void) memcpy(reg, psp->pr_reg, sizeof (reg));
691 
692 	if ((psp->pr_flags & (PR_ASLEEP|PR_VFORKP)) ||
693 	    ((psp->pr_flags & PR_ISTOP) &&
694 	    (psp->pr_why == PR_SYSENTRY ||
695 	    psp->pr_why == PR_SYSEXIT))) {
696 		print_syscall(psp, reg);
697 		h->ignore_frame = 1;
698 	} else {
699 		h->ignore_frame = 0;
700 	}
701 
702 	(void) Pstack_iter(h->proc, reg, print_frame, h);
703 }
704 
705 /*ARGSUSED*/
706 static int
707 jvm_object_iter(void *cd, const prmap_t *pmp, const char *obj)
708 {
709 	char path[PATH_MAX];
710 	char *name;
711 	char *s1, *s2;
712 	struct ps_prochandle *Pr = cd;
713 
714 	if ((name = strstr(obj, "/libjvm.so")) == NULL)
715 		name = strstr(obj, "/libjvm_g.so");
716 
717 	if (name) {
718 		(void) strcpy(path, obj);
719 		if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) {
720 			s1 = name;
721 			s2 = path + (s1 - obj);
722 			(void) strcpy(s2, "/64");
723 			s2 += 3;
724 			(void) strcpy(s2, s1);
725 		}
726 
727 		s1 = strstr(obj, ".so");
728 		s2 = strstr(path, ".so");
729 		(void) strcpy(s2, "_db");
730 		s2 += 3;
731 		(void) strcpy(s2, s1);
732 
733 		if ((libjvm = dlopen(path, RTLD_LAZY|RTLD_GLOBAL)) != NULL)
734 			return (1);
735 	}
736 
737 	return (0);
738 }
739 
740 static jvm_agent_t *
741 load_libjvm(struct ps_prochandle *Pr)
742 {
743 	jvm_agent_t *ret;
744 
745 	/*
746 	 * Iterate through all the loaded objects in the target, looking
747 	 * for libjvm.so.  If we find libjvm.so we'll try to load the
748 	 * corresponding libjvm_db.so that lives in the same directory.
749 	 *
750 	 * At first glance it seems like we'd want to use
751 	 * Pobject_iter_resolved() here since we'd want to make sure that
752 	 * we have the full path to the libjvm.so.  But really, we don't
753 	 * want that since we're going to be dlopen()ing a library and
754 	 * executing code from that path, and therefore we don't want to
755 	 * load any library code that could be from a zone since it could
756 	 * have been replaced with a trojan.  Hence, we use Pobject_iter().
757 	 * So if we're debugging java processes in a zone from the global
758 	 * zone, and we want to get proper java stack stack frames, then
759 	 * the same jvm that is running within the zone needs to be
760 	 * installed in the global zone.
761 	 */
762 	(void) Pobject_iter(Pr, jvm_object_iter, Pr);
763 
764 	if (libjvm) {
765 		j_agent_create = (j_agent_create_f)
766 		    dlsym(libjvm, "Jagent_create");
767 		j_agent_destroy = (j_agent_destroy_f)
768 		    dlsym(libjvm, "Jagent_destroy");
769 		j_frame_iter = (j_frame_iter_f)
770 		    dlsym(libjvm, "Jframe_iter");
771 
772 		if (j_agent_create == NULL || j_agent_destroy == NULL ||
773 		    j_frame_iter == NULL ||
774 		    (ret = j_agent_create(Pr, JVM_DB_VERSION)) == NULL) {
775 			reset_libjvm(NULL);
776 			return (NULL);
777 		}
778 
779 		return (ret);
780 	}
781 
782 	return (NULL);
783 }
784 
785 static void
786 reset_libjvm(jvm_agent_t *agent)
787 {
788 	if (libjvm) {
789 		if (agent)
790 			j_agent_destroy(agent);
791 
792 		(void) dlclose(libjvm);
793 	}
794 
795 	j_agent_create = NULL;
796 	j_agent_destroy = NULL;
797 	j_frame_iter = NULL;
798 	libjvm = NULL;
799 }
800 
801 /*ARGSUSED*/
802 static int
803 python_object_iter(void *cd, const prmap_t *pmp, const char *obj)
804 {
805 	char path[PATH_MAX];
806 	char *name;
807 	char *s1, *s2;
808 	struct ps_prochandle *Pr = cd;
809 
810 	name = strstr(obj, "/libpython");
811 
812 	if (name) {
813 		(void) strcpy(path, obj);
814 		if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) {
815 			s1 = name;
816 			s2 = path + (s1 - obj);
817 			(void) strcpy(s2, "/64");
818 			s2 += 3;
819 			(void) strcpy(s2, s1);
820 		}
821 
822 		s1 = strstr(obj, ".so");
823 		s2 = strstr(path, ".so");
824 		(void) strcpy(s2, "_db");
825 		s2 += 3;
826 		(void) strcpy(s2, s1);
827 
828 		if ((libpython = dlopen(path, RTLD_LAZY|RTLD_GLOBAL)) != NULL)
829 			return (1);
830 	}
831 
832 	return (0);
833 }
834 
835 static pydb_agent_t *
836 load_libpython(struct ps_prochandle *Pr)
837 {
838 	pydb_agent_t *pdb;
839 
840 	(void) Pobject_iter(Pr, python_object_iter, Pr);
841 
842 	if (libpython) {
843 		pydb_agent_create = (pydb_agent_create_f)
844 		    dlsym(libpython, "pydb_agent_create");
845 		pydb_agent_destroy = (pydb_agent_destroy_f)
846 		    dlsym(libpython, "pydb_agent_destroy");
847 		pydb_pc_frameinfo = (pydb_pc_frameinfo_f)
848 		    dlsym(libpython, "pydb_pc_frameinfo");
849 
850 		if (pydb_agent_create == NULL || pydb_agent_destroy == NULL ||
851 		    pydb_pc_frameinfo == NULL) {
852 			(void) dlclose(libpython);
853 			libpython = NULL;
854 			return (NULL);
855 		}
856 
857 		pdb = pydb_agent_create(Pr, PYDB_VERSION);
858 		if (pdb == NULL) {
859 			(void) dlclose(libpython);
860 			libpython = NULL;
861 			return (NULL);
862 		}
863 		return (pdb);
864 	}
865 
866 	return (NULL);
867 }
868 
869 static void
870 reset_libpython(pydb_agent_t *pdb)
871 {
872 	if (libpython != NULL) {
873 		if (pdb != NULL) {
874 			pydb_agent_destroy(pdb);
875 		}
876 		(void) dlclose(libpython);
877 	}
878 
879 	libpython = NULL;
880 	pydb_agent_create = NULL;
881 	pydb_agent_destroy = NULL;
882 	pydb_pc_frameinfo = NULL;
883 }
884