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