Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libproc/common/Pcontrol.c
+++ new/usr/src/lib/libproc/common/Pcontrol.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 *
26 26 * Portions Copyright 2007 Chad Mynhier
27 27 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
28 28 * Copyright (c) 2013 by Delphix. All rights reserved.
29 29 * Copyright 2015, Joyent, Inc.
30 30 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
31 31 * Copyright 2023 Oxide Computer Company
32 32 */
33 33
34 34 #include <assert.h>
35 35 #include <stdio.h>
36 36 #include <stdlib.h>
37 37 #include <unistd.h>
38 38 #include <ctype.h>
39 39 #include <fcntl.h>
40 40 #include <string.h>
41 41 #include <strings.h>
42 42 #include <memory.h>
43 43 #include <errno.h>
44 44 #include <dirent.h>
45 45 #include <limits.h>
46 46 #include <signal.h>
47 47 #include <atomic.h>
48 48 #include <zone.h>
49 49 #include <sys/types.h>
50 50 #include <sys/uio.h>
51 51 #include <sys/stat.h>
52 52 #include <sys/resource.h>
53 53 #include <sys/param.h>
54 54 #include <sys/stack.h>
55 55 #include <sys/fault.h>
56 56 #include <sys/syscall.h>
57 57 #include <sys/sysmacros.h>
58 58 #include <sys/systeminfo.h>
59 59 #include <sys/secflags.h>
60 60
61 61 #include "libproc.h"
62 62 #include "Pcontrol.h"
63 63 #include "Putil.h"
64 64 #include "P32ton.h"
65 65
66 66 int _libproc_debug; /* set non-zero to enable debugging printfs */
67 67 int _libproc_no_qsort; /* set non-zero to inhibit sorting */
68 68 /* of symbol tables */
69 69 int _libproc_incore_elf; /* only use in-core elf data */
70 70
71 71 sigset_t blockable_sigs; /* signals to block when we need to be safe */
72 72 static int minfd; /* minimum file descriptor returned by dupfd(fd, 0) */
73 73 char procfs_path[PATH_MAX] = "/proc";
74 74
75 75 /*
76 76 * Function prototypes for static routines in this module.
77 77 */
78 78 static void deadcheck(struct ps_prochandle *);
79 79 static void restore_tracing_flags(struct ps_prochandle *);
80 80 static void Lfree_internal(struct ps_prochandle *, struct ps_lwphandle *);
81 81 static prheader_t *read_lfile(struct ps_prochandle *, const char *);
82 82
83 83 /*
84 84 * Ops vector functions for live processes.
85 85 */
86 86
87 87 /*ARGSUSED*/
88 88 static ssize_t
89 89 Pread_live(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
90 90 void *data)
91 91 {
92 92 return (pread(P->asfd, buf, n, (off_t)addr));
93 93 }
94 94
95 95 /*ARGSUSED*/
96 96 static ssize_t
97 97 Pwrite_live(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
98 98 void *data)
99 99 {
100 100 return (pwrite(P->asfd, buf, n, (off_t)addr));
101 101 }
102 102
103 103 /*ARGSUSED*/
104 104 static int
105 105 Pread_maps_live(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp,
106 106 void *data)
107 107 {
108 108 char mapfile[PATH_MAX];
109 109 int mapfd;
110 110 struct stat statb;
111 111 ssize_t nmap;
112 112 prmap_t *Pmap = NULL;
113 113
114 114 (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map",
115 115 procfs_path, (int)P->pid);
116 116 if ((mapfd = open(mapfile, O_RDONLY)) < 0 ||
117 117 fstat(mapfd, &statb) != 0 ||
118 118 statb.st_size < sizeof (prmap_t) ||
119 119 (Pmap = malloc(statb.st_size)) == NULL ||
120 120 (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 ||
121 121 (nmap /= sizeof (prmap_t)) == 0) {
122 122 if (Pmap != NULL)
123 123 free(Pmap);
124 124 if (mapfd >= 0)
125 125 (void) close(mapfd);
126 126 Preset_maps(P); /* utter failure; destroy tables */
127 127 return (-1);
128 128 }
129 129 (void) close(mapfd);
130 130
131 131 *Pmapp = Pmap;
132 132 *nmapp = nmap;
133 133
134 134 return (0);
135 135 }
136 136
137 137 /*ARGSUSED*/
138 138 static void
139 139 Pread_aux_live(struct ps_prochandle *P, auxv_t **auxvp, int *nauxp, void *data)
140 140 {
141 141 char auxfile[64];
142 142 int fd;
143 143 struct stat statb;
144 144 auxv_t *auxv;
145 145 ssize_t naux;
146 146
147 147 (void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv",
148 148 procfs_path, (int)P->pid);
149 149 if ((fd = open(auxfile, O_RDONLY)) < 0) {
150 150 dprintf("%s: failed to open %s: %s\n",
151 151 __func__, auxfile, strerror(errno));
152 152 return;
153 153 }
154 154
155 155 if (fstat(fd, &statb) == 0 &&
156 156 statb.st_size >= sizeof (auxv_t) &&
157 157 (auxv = malloc(statb.st_size + sizeof (auxv_t))) != NULL) {
158 158 if ((naux = read(fd, auxv, statb.st_size)) < 0 ||
159 159 (naux /= sizeof (auxv_t)) < 1) {
160 160 dprintf("%s: read failed: %s\n",
161 161 __func__, strerror(errno));
162 162 free(auxv);
163 163 } else {
164 164 auxv[naux].a_type = AT_NULL;
165 165 auxv[naux].a_un.a_val = 0L;
166 166
167 167 *auxvp = auxv;
168 168 *nauxp = (int)naux;
169 169 }
170 170 }
171 171
172 172 (void) close(fd);
173 173 }
174 174
175 175 /*ARGSUSED*/
176 176 static int
177 177 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
178 178 {
179 179 return (proc_get_cred(P->pid, pcrp, ngroups));
180 180 }
181 181
182 182 /* ARGSUSED */
183 183 static int
184 184 Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data)
185 185 {
186 186 return (proc_get_secflags(P->pid, psf));
187 187 }
188 188
189 189 /*ARGSUSED*/
190 190 static int
191 191 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
192 192 {
193 193 prpriv_t *pp;
194 194
195 195 pp = proc_get_priv(P->pid);
196 196 if (pp == NULL) {
197 197 return (-1);
198 198 }
199 199
200 200 *pprv = pp;
201 201 return (0);
202 202 }
203 203
204 204 /*ARGSUSED*/
205 205 static const psinfo_t *
206 206 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
207 207 {
208 208 if (proc_get_psinfo(P->pid, psinfo) == -1)
209 209 return (NULL);
210 210
211 211 return (psinfo);
212 212 }
213 213
214 214 /*ARGSUSED*/
215 215 static prheader_t *
216 216 Plstatus_live(struct ps_prochandle *P, void *data)
217 217 {
218 218 return (read_lfile(P, "lstatus"));
219 219 }
220 220
221 221 /*ARGSUSED*/
222 222 static prheader_t *
223 223 Plpsinfo_live(struct ps_prochandle *P, void *data)
224 224 {
225 225 return (read_lfile(P, "lpsinfo"));
226 226 }
227 227
228 228 /*ARGSUSED*/
229 229 static char *
230 230 Pplatform_live(struct ps_prochandle *P, char *s, size_t n, void *data)
231 231 {
232 232 if (sysinfo(SI_PLATFORM, s, n) == -1)
233 233 return (NULL);
234 234 return (s);
235 235 }
236 236
237 237 /*ARGSUSED*/
238 238 static int
239 239 Puname_live(struct ps_prochandle *P, struct utsname *u, void *data)
240 240 {
241 241 return (uname(u));
242 242 }
243 243
244 244 /*ARGSUSED*/
245 245 static char *
246 246 Pzonename_live(struct ps_prochandle *P, char *s, size_t n, void *data)
247 247 {
248 248 if (getzonenamebyid(P->status.pr_zoneid, s, n) < 0)
249 249 return (NULL);
250 250 s[n - 1] = '\0';
251 251 return (s);
252 252 }
253 253
254 254 /*
255 255 * Callback function for Pfindexec(). We return a match if we can stat the
256 256 * suggested pathname and confirm its device and inode number match our
257 257 * previous information about the /proc/<pid>/object/a.out file.
258 258 */
259 259 static int
260 260 stat_exec(const char *path, void *arg)
261 261 {
262 262 struct stat64 *stp = arg;
263 263 struct stat64 st;
264 264
265 265 return (stat64(path, &st) == 0 && S_ISREG(st.st_mode) &&
266 266 stp->st_dev == st.st_dev && stp->st_ino == st.st_ino);
267 267 }
268 268
269 269 /*ARGSUSED*/
270 270 static char *
271 271 Pexecname_live(struct ps_prochandle *P, char *buf, size_t buflen, void *data)
272 272 {
273 273 char exec_name[PATH_MAX];
274 274 char cwd[PATH_MAX];
275 275 char proc_cwd[64];
276 276 struct stat64 st;
277 277 int ret;
278 278
279 279 /*
280 280 * Try to get the path information first.
281 281 */
282 282 (void) snprintf(exec_name, sizeof (exec_name),
283 283 "%s/%d/path/a.out", procfs_path, (int)P->pid);
284 284 if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) {
285 285 buf[ret] = '\0';
286 286 (void) Pfindobj(P, buf, buf, buflen);
287 287 return (buf);
288 288 }
289 289
290 290 /*
291 291 * Stat the executable file so we can compare Pfindexec's
292 292 * suggestions to the actual device and inode number.
293 293 */
294 294 (void) snprintf(exec_name, sizeof (exec_name),
295 295 "%s/%d/object/a.out", procfs_path, (int)P->pid);
296 296
297 297 if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode))
298 298 return (NULL);
299 299
300 300 /*
301 301 * Attempt to figure out the current working directory of the
302 302 * target process. This only works if the target process has
303 303 * not changed its current directory since it was exec'd.
304 304 */
305 305 (void) snprintf(proc_cwd, sizeof (proc_cwd),
306 306 "%s/%d/path/cwd", procfs_path, (int)P->pid);
307 307
308 308 if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0)
309 309 cwd[ret] = '\0';
310 310
311 311 (void) Pfindexec(P, ret > 0 ? cwd : NULL, stat_exec, &st);
312 312
313 313 return (NULL);
314 314 }
315 315
316 316 #if defined(__i386) || defined(__amd64)
317 317 /*ARGSUSED*/
318 318 static int
319 319 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
320 320 {
321 321 return (proc_get_ldt(P->pid, pldt, nldt));
322 322 }
323 323 #endif
324 324
325 325 static const ps_ops_t P_live_ops = {
326 326 .pop_pread = Pread_live,
327 327 .pop_pwrite = Pwrite_live,
328 328 .pop_read_maps = Pread_maps_live,
329 329 .pop_read_aux = Pread_aux_live,
330 330 .pop_cred = Pcred_live,
331 331 .pop_priv = Ppriv_live,
332 332 .pop_psinfo = Ppsinfo_live,
333 333 .pop_lstatus = Plstatus_live,
334 334 .pop_lpsinfo = Plpsinfo_live,
335 335 .pop_platform = Pplatform_live,
336 336 .pop_uname = Puname_live,
337 337 .pop_zonename = Pzonename_live,
338 338 .pop_execname = Pexecname_live,
339 339 .pop_secflags = Psecflags_live,
340 340 #if defined(__i386) || defined(__amd64)
341 341 .pop_ldt = Pldt_live
|
↓ open down ↓ |
341 lines elided |
↑ open up ↑ |
342 342 #endif
343 343 };
344 344
345 345 /*
346 346 * This is the library's .init handler.
347 347 */
348 348 #pragma init(_libproc_init)
349 349 void
350 350 _libproc_init(void)
351 351 {
352 + const char *root;
353 +
352 354 _libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
353 355 _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
354 356 _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
355 357
358 + if ((root = zone_get_nroot()) != NULL)
359 + (void) snprintf(procfs_path, sizeof (procfs_path), "%s/proc",
360 + root);
361 +
356 362 (void) sigfillset(&blockable_sigs);
357 363 (void) sigdelset(&blockable_sigs, SIGKILL);
358 364 (void) sigdelset(&blockable_sigs, SIGSTOP);
359 365 }
360 366
361 367 void
362 368 Pset_procfs_path(const char *path)
363 369 {
364 370 (void) snprintf(procfs_path, sizeof (procfs_path), "%s", path);
365 371 }
366 372
367 373 /*
368 374 * Call set_minfd() once before calling dupfd() several times.
369 375 * We assume that the application will not reduce its current file
370 376 * descriptor limit lower than 512 once it has set at least that value.
371 377 */
372 378 int
373 379 set_minfd(void)
374 380 {
375 381 static mutex_t minfd_lock = DEFAULTMUTEX;
376 382 struct rlimit rlim;
377 383 int fd;
378 384
379 385 if ((fd = minfd) < 256) {
380 386 (void) mutex_lock(&minfd_lock);
381 387 if ((fd = minfd) < 256) {
382 388 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0)
383 389 rlim.rlim_cur = rlim.rlim_max = 0;
384 390 if (rlim.rlim_cur >= 512)
385 391 fd = 256;
386 392 else if ((fd = rlim.rlim_cur / 2) < 3)
387 393 fd = 3;
388 394 membar_producer();
389 395 minfd = fd;
390 396 }
391 397 (void) mutex_unlock(&minfd_lock);
392 398 }
393 399 return (fd);
394 400 }
395 401
396 402 int
397 403 dupfd(int fd, int dfd)
398 404 {
399 405 int mfd;
400 406
401 407 /*
402 408 * Make fd be greater than 255 (the 32-bit stdio limit),
403 409 * or at least make it greater than 2 so that the
404 410 * program will work when spawned by init(8).
405 411 * Also, if dfd is non-zero, dup the fd to be dfd.
406 412 */
407 413 if ((mfd = minfd) == 0)
408 414 mfd = set_minfd();
409 415 if (dfd > 0 || (0 <= fd && fd < mfd)) {
410 416 if (dfd <= 0)
411 417 dfd = mfd;
412 418 dfd = fcntl(fd, F_DUPFD, dfd);
413 419 (void) close(fd);
414 420 fd = dfd;
415 421 }
416 422 /*
417 423 * Mark it close-on-exec so any created process doesn't inherit it.
418 424 */
419 425 if (fd >= 0)
420 426 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
421 427 return (fd);
422 428 }
423 429
424 430 /*
425 431 * Create a new controlled process.
426 432 * Leave it stopped on successful exit from exec() or execve().
427 433 * Return an opaque pointer to its process control structure.
428 434 * Return NULL if process cannot be created (fork()/exec() not successful).
429 435 */
430 436 struct ps_prochandle *
431 437 Pxcreate(const char *file, /* executable file name */
432 438 char *const *argv, /* argument vector */
433 439 char *const *envp, /* environment */
434 440 int *perr, /* pointer to error return code */
435 441 char *path, /* if non-null, holds exec path name on return */
436 442 size_t len) /* size of the path buffer */
437 443 {
438 444 char execpath[PATH_MAX];
439 445 char procname[PATH_MAX];
440 446 struct ps_prochandle *P;
441 447 pid_t pid;
442 448 int fd;
443 449 char *fname;
444 450 int rc;
445 451 int lasterrno = 0;
446 452
447 453 if (len == 0) /* zero length, no path */
448 454 path = NULL;
449 455 if (path != NULL)
450 456 *path = '\0';
451 457
452 458 if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
453 459 *perr = C_STRANGE;
454 460 return (NULL);
455 461 }
456 462
457 463 if ((pid = fork1()) == -1) {
458 464 free(P);
459 465 *perr = C_FORK;
460 466 return (NULL);
461 467 }
462 468
463 469 if (pid == 0) { /* child process */
464 470 id_t id;
465 471 extern char **environ;
466 472
467 473 /*
468 474 * If running setuid or setgid, reset credentials to normal.
469 475 */
470 476 if ((id = getgid()) != getegid())
471 477 (void) setgid(id);
472 478 if ((id = getuid()) != geteuid())
473 479 (void) setuid(id);
474 480
475 481 Pcreate_callback(P); /* execute callback (see below) */
476 482 (void) pause(); /* wait for PRSABORT from parent */
477 483
478 484 /*
479 485 * This is ugly. There is no execvep() function that takes a
480 486 * path and an environment. We cheat here by replacing the
481 487 * global 'environ' variable right before we call this.
482 488 */
483 489 if (envp)
484 490 environ = (char **)envp;
485 491
486 492 (void) execvp(file, argv); /* execute the program */
487 493 _exit(127);
488 494 }
489 495
490 496 /*
491 497 * Initialize the process structure.
492 498 */
493 499 (void) memset(P, 0, sizeof (*P));
494 500 (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
495 501 P->flags |= CREATED;
496 502 P->state = PS_RUN;
497 503 P->pid = pid;
498 504 P->asfd = -1;
499 505 P->ctlfd = -1;
500 506 P->statfd = -1;
501 507 P->agentctlfd = -1;
502 508 P->agentstatfd = -1;
503 509 Pinit_ops(&P->ops, &P_live_ops);
504 510 Pinitsym(P);
505 511 Pinitfd(P);
506 512
507 513 /*
508 514 * Open the /proc/pid files.
509 515 */
510 516 (void) snprintf(procname, sizeof (procname), "%s/%d/",
511 517 procfs_path, (int)pid);
512 518 fname = procname + strlen(procname);
513 519 (void) set_minfd();
514 520
515 521 /*
516 522 * Exclusive write open advises others not to interfere.
517 523 * There is no reason for any of these open()s to fail.
518 524 */
519 525 (void) strcpy(fname, "as");
520 526 if ((fd = open(procname, (O_RDWR|O_EXCL))) < 0 ||
521 527 (fd = dupfd(fd, 0)) < 0) {
522 528 dprintf("Pcreate: failed to open %s: %s\n",
523 529 procname, strerror(errno));
524 530 rc = C_STRANGE;
525 531 goto bad;
526 532 }
527 533 P->asfd = fd;
528 534
529 535 (void) strcpy(fname, "status");
530 536 if ((fd = open(procname, O_RDONLY)) < 0 ||
531 537 (fd = dupfd(fd, 0)) < 0) {
532 538 dprintf("Pcreate: failed to open %s: %s\n",
533 539 procname, strerror(errno));
534 540 rc = C_STRANGE;
535 541 goto bad;
536 542 }
537 543 P->statfd = fd;
538 544
539 545 (void) strcpy(fname, "ctl");
540 546 if ((fd = open(procname, O_WRONLY)) < 0 ||
541 547 (fd = dupfd(fd, 0)) < 0) {
542 548 dprintf("Pcreate: failed to open %s: %s\n",
543 549 procname, strerror(errno));
544 550 rc = C_STRANGE;
545 551 goto bad;
546 552 }
547 553 P->ctlfd = fd;
548 554
549 555 (void) Pstop(P, 0); /* stop the controlled process */
550 556
551 557 /*
552 558 * Wait for process to sleep in pause().
553 559 * If the process has already called pause(), then it should be
554 560 * stopped (PR_REQUESTED) while asleep in pause and we are done.
555 561 * Else we set up to catch entry/exit to pause() and set the process
556 562 * running again, expecting it to stop when it reaches pause().
557 563 * There is no reason for this to fail other than an interrupt.
558 564 */
559 565 (void) Psysentry(P, SYS_pause, 1);
560 566 (void) Psysexit(P, SYS_pause, 1);
561 567 for (;;) {
562 568 if (P->state == PS_STOP &&
563 569 P->status.pr_lwp.pr_syscall == SYS_pause &&
564 570 (P->status.pr_lwp.pr_why == PR_REQUESTED ||
565 571 P->status.pr_lwp.pr_why == PR_SYSENTRY ||
566 572 P->status.pr_lwp.pr_why == PR_SYSEXIT))
567 573 break;
568 574
569 575 if (P->state != PS_STOP || /* interrupt or process died */
570 576 Psetrun(P, 0, 0) != 0) { /* can't restart */
571 577 if (errno == EINTR || errno == ERESTART)
572 578 rc = C_INTR;
573 579 else {
574 580 dprintf("Pcreate: Psetrun failed: %s\n",
575 581 strerror(errno));
576 582 rc = C_STRANGE;
577 583 }
578 584 goto bad;
579 585 }
580 586
581 587 (void) Pwait(P, 0);
582 588 }
583 589 (void) Psysentry(P, SYS_pause, 0);
584 590 (void) Psysexit(P, SYS_pause, 0);
585 591
586 592 /*
587 593 * Kick the process off the pause() and catch
588 594 * it again on entry to exec() or exit().
589 595 */
590 596 (void) Psysentry(P, SYS_exit, 1);
591 597 (void) Psysentry(P, SYS_execve, 1);
592 598 if (Psetrun(P, 0, PRSABORT) == -1) {
593 599 dprintf("Pcreate: Psetrun failed: %s\n", strerror(errno));
594 600 rc = C_STRANGE;
595 601 goto bad;
596 602 }
597 603 (void) Pwait(P, 0);
598 604 if (P->state != PS_STOP) {
599 605 dprintf("Pcreate: Pwait failed: %s\n", strerror(errno));
600 606 rc = C_STRANGE;
601 607 goto bad;
602 608 }
603 609
604 610 /*
605 611 * Move the process through instances of failed exec()s
606 612 * to reach the point of stopped on successful exec().
607 613 */
608 614 (void) Psysexit(P, SYS_execve, TRUE);
609 615
610 616 while (P->state == PS_STOP &&
611 617 P->status.pr_lwp.pr_why == PR_SYSENTRY &&
612 618 P->status.pr_lwp.pr_what == SYS_execve) {
613 619 /*
614 620 * Fetch the exec path name now, before we complete
615 621 * the exec(). We may lose the process and be unable
616 622 * to get the information later.
617 623 */
618 624 (void) Pread_string(P, execpath, sizeof (execpath),
619 625 (off_t)P->status.pr_lwp.pr_sysarg[0]);
620 626 if (path != NULL)
621 627 (void) strncpy(path, execpath, len);
622 628 /*
623 629 * Set the process running and wait for
624 630 * it to stop on exit from the exec().
625 631 */
626 632 (void) Psetrun(P, 0, 0);
627 633 (void) Pwait(P, 0);
628 634
629 635 if (P->state == PS_LOST && /* we lost control */
630 636 Preopen(P) != 0) { /* and we can't get it back */
631 637 rc = C_PERM;
632 638 goto bad;
633 639 }
634 640
635 641 /*
636 642 * If the exec() failed, continue the loop, expecting
637 643 * there to be more attempts to exec(), based on PATH.
638 644 */
639 645 if (P->state == PS_STOP &&
640 646 P->status.pr_lwp.pr_why == PR_SYSEXIT &&
641 647 P->status.pr_lwp.pr_what == SYS_execve &&
642 648 (lasterrno = P->status.pr_lwp.pr_errno) != 0) {
643 649 /*
644 650 * The exec() failed. Set the process running and
645 651 * wait for it to stop on entry to the next exec().
646 652 */
647 653 (void) Psetrun(P, 0, 0);
648 654 (void) Pwait(P, 0);
649 655
650 656 continue;
651 657 }
652 658 break;
653 659 }
654 660
655 661 if (P->state == PS_STOP &&
656 662 P->status.pr_lwp.pr_why == PR_SYSEXIT &&
657 663 P->status.pr_lwp.pr_what == SYS_execve &&
658 664 P->status.pr_lwp.pr_errno == 0) {
659 665 /*
660 666 * The process is stopped on successful exec() or execve().
661 667 * Turn off all tracing flags and return success.
662 668 */
663 669 restore_tracing_flags(P);
664 670 #ifndef _LP64
665 671 /* We must be a 64-bit process to deal with a 64-bit process */
666 672 if (P->status.pr_dmodel == PR_MODEL_LP64) {
667 673 rc = C_LP64;
668 674 goto bad;
669 675 }
670 676 #endif
671 677 /*
672 678 * Set run-on-last-close so the controlled process
673 679 * runs even if we die on a signal.
674 680 */
675 681 (void) Psetflags(P, PR_RLC);
676 682 *perr = 0;
677 683 return (P);
678 684 }
679 685
680 686 rc = lasterrno == ENOENT ? C_NOENT : C_NOEXEC;
681 687
682 688 bad:
683 689 (void) kill(pid, SIGKILL);
684 690 if (path != NULL && rc != C_PERM && rc != C_LP64)
685 691 *path = '\0';
686 692 Pfree(P);
687 693 *perr = rc;
688 694 return (NULL);
689 695 }
690 696
691 697 struct ps_prochandle *
692 698 Pcreate(
693 699 const char *file, /* executable file name */
694 700 char *const *argv, /* argument vector */
695 701 int *perr, /* pointer to error return code */
696 702 char *path, /* if non-null, holds exec path name on return */
697 703 size_t len) /* size of the path buffer */
698 704 {
699 705 return (Pxcreate(file, argv, NULL, perr, path, len));
700 706 }
701 707
702 708 /*
703 709 * Return a printable string corresponding to a Pcreate() error return.
704 710 */
705 711 const char *
706 712 Pcreate_error(int error)
707 713 {
708 714 const char *str;
709 715
710 716 switch (error) {
711 717 case C_FORK:
712 718 str = "cannot fork";
713 719 break;
714 720 case C_PERM:
715 721 str = "file is set-id or unreadable";
716 722 break;
717 723 case C_NOEXEC:
718 724 str = "cannot execute file";
719 725 break;
720 726 case C_INTR:
721 727 str = "operation interrupted";
722 728 break;
723 729 case C_LP64:
724 730 str = "program is _LP64, self is not";
725 731 break;
726 732 case C_STRANGE:
727 733 str = "unanticipated system error";
728 734 break;
729 735 case C_NOENT:
730 736 str = "cannot find executable file";
731 737 break;
732 738 default:
733 739 str = "unknown error";
734 740 break;
735 741 }
736 742
737 743 return (str);
738 744 }
739 745
740 746 /*
741 747 * Callback to execute in each child process created with Pcreate() after fork
742 748 * but before it execs the new process image. By default, we do nothing, but
743 749 * by calling this function we allow the client program to define its own
744 750 * version of the function which will interpose on our empty default. This
745 751 * may be useful for clients that need to modify signal dispositions, terminal
746 752 * attributes, or process group and session properties for each new victim.
747 753 */
748 754 /*ARGSUSED*/
749 755 void
750 756 Pcreate_callback(struct ps_prochandle *P)
751 757 {
752 758 /* nothing to do here */
753 759 }
754 760
755 761 /*
756 762 * Grab an existing process.
757 763 * Return an opaque pointer to its process control structure.
758 764 *
759 765 * pid: UNIX process ID.
760 766 * flags:
761 767 * PGRAB_RETAIN Retain tracing flags (default clears all tracing flags).
762 768 * PGRAB_FORCE Grab regardless of whether process is already traced.
763 769 * PGRAB_RDONLY Open the address space file O_RDONLY instead of O_RDWR,
764 770 * and do not open the process control file.
765 771 * PGRAB_NOSTOP Open the process but do not force it to stop.
766 772 * perr: pointer to error return code.
767 773 */
768 774 struct ps_prochandle *
769 775 Pgrab(pid_t pid, int flags, int *perr)
770 776 {
771 777 struct ps_prochandle *P;
772 778 int fd, omode;
773 779 char procname[PATH_MAX];
774 780 char *fname;
775 781 int rc = 0;
776 782
777 783 /*
778 784 * PGRAB_RDONLY means that we do not open the /proc/<pid>/control file,
779 785 * and so it implies RETAIN and NOSTOP since both require control.
780 786 */
781 787 if (flags & PGRAB_RDONLY)
782 788 flags |= PGRAB_RETAIN | PGRAB_NOSTOP;
783 789
784 790 if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
785 791 *perr = G_STRANGE;
786 792 return (NULL);
787 793 }
788 794
789 795 P->asfd = -1;
790 796 P->ctlfd = -1;
791 797 P->statfd = -1;
792 798
793 799 again: /* Come back here if we lose it in the Window of Vulnerability */
794 800 if (P->ctlfd >= 0)
795 801 (void) close(P->ctlfd);
796 802 if (P->asfd >= 0)
797 803 (void) close(P->asfd);
798 804 if (P->statfd >= 0)
799 805 (void) close(P->statfd);
800 806 (void) memset(P, 0, sizeof (*P));
801 807 (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
802 808 P->ctlfd = -1;
803 809 P->asfd = -1;
804 810 P->statfd = -1;
805 811 P->agentctlfd = -1;
806 812 P->agentstatfd = -1;
807 813 Pinit_ops(&P->ops, &P_live_ops);
808 814 Pinitsym(P);
809 815 Pinitfd(P);
810 816
811 817 /*
812 818 * Open the /proc/pid files
813 819 */
814 820 (void) snprintf(procname, sizeof (procname), "%s/%d/",
815 821 procfs_path, (int)pid);
816 822 fname = procname + strlen(procname);
817 823 (void) set_minfd();
818 824
819 825 /*
820 826 * Request exclusive open to avoid grabbing someone else's
821 827 * process and to prevent others from interfering afterwards.
822 828 * If this fails and the 'PGRAB_FORCE' flag is set, attempt to
823 829 * open non-exclusively.
824 830 */
825 831 (void) strcpy(fname, "as");
826 832 omode = (flags & PGRAB_RDONLY) ? O_RDONLY : O_RDWR;
827 833
828 834 if (((fd = open(procname, omode | O_EXCL)) < 0 &&
829 835 (fd = ((flags & PGRAB_FORCE)? open(procname, omode) : -1)) < 0) ||
830 836 (fd = dupfd(fd, 0)) < 0) {
831 837 switch (errno) {
832 838 case ENOENT:
833 839 rc = G_NOPROC;
834 840 break;
835 841 case EACCES:
836 842 case EPERM:
837 843 rc = G_PERM;
838 844 break;
839 845 case EMFILE:
840 846 rc = G_NOFD;
841 847 break;
842 848 case EBUSY:
843 849 if (!(flags & PGRAB_FORCE) || geteuid() != 0) {
844 850 rc = G_BUSY;
845 851 break;
846 852 }
847 853 /* FALLTHROUGH */
848 854 default:
849 855 dprintf("Pgrab: failed to open %s: %s\n",
850 856 procname, strerror(errno));
851 857 rc = G_STRANGE;
852 858 break;
853 859 }
854 860 goto err;
855 861 }
856 862 P->asfd = fd;
857 863
858 864 (void) strcpy(fname, "status");
859 865 if ((fd = open(procname, O_RDONLY)) < 0 ||
860 866 (fd = dupfd(fd, 0)) < 0) {
861 867 switch (errno) {
862 868 case ENOENT:
863 869 rc = G_NOPROC;
864 870 break;
865 871 case EMFILE:
866 872 rc = G_NOFD;
867 873 break;
868 874 default:
869 875 dprintf("Pgrab: failed to open %s: %s\n",
870 876 procname, strerror(errno));
871 877 rc = G_STRANGE;
872 878 break;
873 879 }
874 880 goto err;
875 881 }
876 882 P->statfd = fd;
877 883
878 884 if (!(flags & PGRAB_RDONLY)) {
879 885 (void) strcpy(fname, "ctl");
880 886 if ((fd = open(procname, O_WRONLY)) < 0 ||
881 887 (fd = dupfd(fd, 0)) < 0) {
882 888 switch (errno) {
883 889 case ENOENT:
884 890 rc = G_NOPROC;
885 891 break;
886 892 case EMFILE:
887 893 rc = G_NOFD;
888 894 break;
889 895 default:
890 896 dprintf("Pgrab: failed to open %s: %s\n",
891 897 procname, strerror(errno));
892 898 rc = G_STRANGE;
893 899 break;
894 900 }
895 901 goto err;
896 902 }
897 903 P->ctlfd = fd;
898 904 }
899 905
900 906 P->state = PS_RUN;
901 907 P->pid = pid;
902 908
903 909 /*
904 910 * We are now in the Window of Vulnerability (WoV). The process may
905 911 * exec() a setuid/setgid or unreadable object file between the open()
906 912 * and the PCSTOP. We will get EAGAIN in this case and must start over.
907 913 * As Pstopstatus will trigger the first read() from a /proc file,
908 914 * we also need to handle EOVERFLOW here when 32-bit as an indicator
909 915 * that this process is 64-bit. Finally, if the process has become
910 916 * a zombie (PS_UNDEAD) while we were trying to grab it, just remain
911 917 * silent about this and pretend there was no process.
912 918 */
913 919 if (Pstopstatus(P, PCNULL, 0) != 0) {
914 920 #ifndef _LP64
915 921 if (errno == EOVERFLOW) {
916 922 rc = G_LP64;
917 923 goto err;
918 924 }
919 925 #endif
920 926 if (P->state == PS_LOST) { /* WoV */
921 927 (void) mutex_destroy(&P->proc_lock);
922 928 goto again;
923 929 }
924 930
925 931 if (P->state == PS_UNDEAD)
926 932 rc = G_NOPROC;
927 933 else
928 934 rc = G_STRANGE;
929 935
930 936 goto err;
931 937 }
932 938
933 939 /*
934 940 * If the process is a system process, we can't control it even as root
935 941 */
936 942 if (P->status.pr_flags & PR_ISSYS) {
937 943 rc = G_SYS;
938 944 goto err;
939 945 }
940 946 #ifndef _LP64
941 947 /*
942 948 * We must be a 64-bit process to deal with a 64-bit process
943 949 */
944 950 if (P->status.pr_dmodel == PR_MODEL_LP64) {
945 951 rc = G_LP64;
946 952 goto err;
947 953 }
948 954 #endif
949 955
950 956 /*
951 957 * Remember the status for use by Prelease().
952 958 */
953 959 P->orig_status = P->status; /* structure copy */
954 960
955 961 /*
956 962 * Before stopping the process, make sure we are not grabbing ourselves.
957 963 * If we are, make sure we are doing it PGRAB_RDONLY.
958 964 */
959 965 if (pid == getpid()) {
960 966 /*
961 967 * Verify that the process is really ourself:
962 968 * Set a magic number, read it through the
963 969 * /proc file and see if the results match.
964 970 */
965 971 uint32_t magic1 = 0;
966 972 uint32_t magic2 = 2;
967 973
968 974 errno = 0;
969 975
970 976 if (Pread(P, &magic2, sizeof (magic2), (uintptr_t)&magic1)
971 977 == sizeof (magic2) &&
972 978 magic2 == 0 &&
973 979 (magic1 = 0xfeedbeef) &&
974 980 Pread(P, &magic2, sizeof (magic2), (uintptr_t)&magic1)
975 981 == sizeof (magic2) &&
976 982 magic2 == 0xfeedbeef &&
977 983 !(flags & PGRAB_RDONLY)) {
978 984 rc = G_SELF;
979 985 goto err;
980 986 }
981 987 }
982 988
983 989 /*
984 990 * If the process is already stopped or has been directed
985 991 * to stop via /proc, do not set run-on-last-close.
986 992 */
987 993 if (!(P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) &&
988 994 !(flags & PGRAB_RDONLY)) {
989 995 /*
990 996 * Mark the process run-on-last-close so
991 997 * it runs even if we die from SIGKILL.
992 998 */
993 999 if (Psetflags(P, PR_RLC) != 0) {
994 1000 if (errno == EAGAIN) { /* WoV */
995 1001 (void) mutex_destroy(&P->proc_lock);
996 1002 goto again;
997 1003 }
998 1004 if (errno == ENOENT) /* No complaint about zombies */
999 1005 rc = G_ZOMB;
1000 1006 else {
1001 1007 dprintf("Pgrab: failed to set RLC\n");
1002 1008 rc = G_STRANGE;
1003 1009 }
1004 1010 goto err;
1005 1011 }
1006 1012 }
1007 1013
1008 1014 /*
1009 1015 * If a stop directive is pending and the process has not yet stopped,
1010 1016 * then synchronously wait for the stop directive to take effect.
1011 1017 * Limit the time spent waiting for the process to stop by iterating
1012 1018 * at most 10 times. The time-out of 20 ms corresponds to the time
1013 1019 * between sending the stop directive and the process actually stopped
1014 1020 * as measured by DTrace on a slow, busy system. If the process doesn't
1015 1021 * stop voluntarily, clear the PR_DSTOP flag so that the code below
1016 1022 * forces the process to stop.
1017 1023 */
1018 1024 if (!(flags & PGRAB_RDONLY)) {
1019 1025 int niter = 0;
1020 1026 while ((P->status.pr_lwp.pr_flags & (PR_STOPPED|PR_DSTOP)) ==
1021 1027 PR_DSTOP && niter < 10 &&
1022 1028 Pstopstatus(P, PCTWSTOP, 20) != 0) {
1023 1029 niter++;
1024 1030 if (flags & PGRAB_NOSTOP)
1025 1031 break;
1026 1032 }
1027 1033 if (niter == 10 && !(flags & PGRAB_NOSTOP)) {
1028 1034 /* Try it harder down below */
1029 1035 P->status.pr_lwp.pr_flags &= ~PR_DSTOP;
1030 1036 }
1031 1037 }
1032 1038
1033 1039 /*
1034 1040 * If the process is not already stopped or directed to stop
1035 1041 * and PGRAB_NOSTOP was not specified, stop the process now.
1036 1042 */
1037 1043 if (!(P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) &&
1038 1044 !(flags & PGRAB_NOSTOP)) {
1039 1045 /*
1040 1046 * Stop the process, get its status and signal/syscall masks.
1041 1047 */
1042 1048 if (((P->status.pr_lwp.pr_flags & PR_STOPPED) &&
1043 1049 Pstopstatus(P, PCDSTOP, 0) != 0) ||
1044 1050 Pstopstatus(P, PCSTOP, 2000) != 0) {
1045 1051 #ifndef _LP64
1046 1052 if (errno == EOVERFLOW) {
1047 1053 rc = G_LP64;
1048 1054 goto err;
1049 1055 }
1050 1056 #endif
1051 1057 if (P->state == PS_LOST) { /* WoV */
1052 1058 (void) mutex_destroy(&P->proc_lock);
1053 1059 goto again;
1054 1060 }
1055 1061 if ((errno != EINTR && errno != ERESTART) ||
1056 1062 (P->state != PS_STOP &&
1057 1063 !(P->status.pr_flags & PR_DSTOP))) {
1058 1064 if (P->state != PS_RUN && errno != ENOENT) {
1059 1065 dprintf("Pgrab: failed to PCSTOP\n");
1060 1066 rc = G_STRANGE;
1061 1067 } else {
1062 1068 rc = G_ZOMB;
1063 1069 }
1064 1070 goto err;
1065 1071 }
1066 1072 }
1067 1073
1068 1074 /*
1069 1075 * Process should now either be stopped via /proc or there
1070 1076 * should be an outstanding stop directive.
1071 1077 */
1072 1078 if (!(P->status.pr_flags & (PR_ISTOP|PR_DSTOP))) {
1073 1079 dprintf("Pgrab: process is not stopped\n");
1074 1080 rc = G_STRANGE;
1075 1081 goto err;
1076 1082 }
1077 1083 #ifndef _LP64
1078 1084 /*
1079 1085 * Test this again now because the 32-bit victim process may
1080 1086 * have exec'd a 64-bit process in the meantime.
1081 1087 */
1082 1088 if (P->status.pr_dmodel == PR_MODEL_LP64) {
1083 1089 rc = G_LP64;
1084 1090 goto err;
1085 1091 }
1086 1092 #endif
1087 1093 }
1088 1094
1089 1095 /*
1090 1096 * Cancel all tracing flags unless the PGRAB_RETAIN flag is set.
1091 1097 */
1092 1098 if (!(flags & PGRAB_RETAIN)) {
1093 1099 (void) Psysentry(P, 0, FALSE);
1094 1100 (void) Psysexit(P, 0, FALSE);
1095 1101 (void) Psignal(P, 0, FALSE);
1096 1102 (void) Pfault(P, 0, FALSE);
1097 1103 Psync(P);
1098 1104 }
1099 1105
1100 1106 *perr = 0;
1101 1107 return (P);
1102 1108
1103 1109 err:
1104 1110 Pfree(P);
1105 1111 *perr = rc;
1106 1112 return (NULL);
1107 1113 }
1108 1114
1109 1115 /*
1110 1116 * Return a printable string corresponding to a Pgrab() error return.
1111 1117 */
1112 1118 const char *
1113 1119 Pgrab_error(int error)
1114 1120 {
1115 1121 const char *str;
1116 1122
1117 1123 switch (error) {
1118 1124 case G_NOPROC:
1119 1125 str = "no such process";
1120 1126 break;
1121 1127 case G_NOCORE:
1122 1128 str = "no such core file";
1123 1129 break;
1124 1130 case G_NOPROCORCORE:
1125 1131 str = "no such process or core file";
1126 1132 break;
1127 1133 case G_NOEXEC:
1128 1134 str = "cannot find executable file";
1129 1135 break;
1130 1136 case G_ZOMB:
1131 1137 str = "zombie process";
1132 1138 break;
1133 1139 case G_PERM:
1134 1140 str = "permission denied";
1135 1141 break;
1136 1142 case G_BUSY:
1137 1143 str = "process is traced";
1138 1144 break;
1139 1145 case G_SYS:
1140 1146 str = "system process";
1141 1147 break;
1142 1148 case G_SELF:
1143 1149 str = "attempt to grab self";
1144 1150 break;
1145 1151 case G_INTR:
1146 1152 str = "operation interrupted";
1147 1153 break;
1148 1154 case G_LP64:
1149 1155 str = "program is _LP64, self is not";
1150 1156 break;
1151 1157 case G_FORMAT:
1152 1158 str = "file is not an ELF core file";
1153 1159 break;
1154 1160 case G_ELF:
1155 1161 str = "libelf error";
1156 1162 break;
1157 1163 case G_NOTE:
1158 1164 str = "core file is corrupt or missing required data";
1159 1165 break;
1160 1166 case G_STRANGE:
1161 1167 str = "unanticipated system error";
1162 1168 break;
1163 1169 case G_ISAINVAL:
1164 1170 str = "wrong ELF machine type";
1165 1171 break;
1166 1172 case G_BADLWPS:
1167 1173 str = "bad lwp specification";
1168 1174 break;
1169 1175 case G_NOFD:
1170 1176 str = "too many open files";
1171 1177 break;
1172 1178 default:
1173 1179 str = "unknown error";
1174 1180 break;
1175 1181 }
1176 1182
1177 1183 return (str);
1178 1184 }
1179 1185
1180 1186 /*
1181 1187 * Free a process control structure.
1182 1188 * Close the file descriptors but don't do the Prelease logic.
1183 1189 */
1184 1190 void
1185 1191 Pfree(struct ps_prochandle *P)
1186 1192 {
1187 1193 uint_t i;
1188 1194 fd_info_t *fip;
1189 1195
1190 1196 if (P->ucaddrs != NULL) {
1191 1197 free(P->ucaddrs);
1192 1198 P->ucaddrs = NULL;
1193 1199 P->ucnelems = 0;
1194 1200 }
1195 1201
1196 1202 (void) mutex_lock(&P->proc_lock);
1197 1203 if (P->hashtab != NULL) {
1198 1204 struct ps_lwphandle *L;
1199 1205 for (i = 0; i < HASHSIZE; i++) {
1200 1206 while ((L = P->hashtab[i]) != NULL)
1201 1207 Lfree_internal(P, L);
1202 1208 }
1203 1209 free(P->hashtab);
1204 1210 }
1205 1211
1206 1212 while ((fip = list_remove_head(&P->fd_head)) != NULL) {
1207 1213 proc_fdinfo_free(fip->fd_info);
1208 1214 free(fip);
1209 1215 }
1210 1216 (void) mutex_unlock(&P->proc_lock);
1211 1217 (void) mutex_destroy(&P->proc_lock);
1212 1218
1213 1219 free(P->zoneroot);
1214 1220
1215 1221 if (P->agentctlfd >= 0)
1216 1222 (void) close(P->agentctlfd);
1217 1223 if (P->agentstatfd >= 0)
1218 1224 (void) close(P->agentstatfd);
1219 1225 if (P->ctlfd >= 0)
1220 1226 (void) close(P->ctlfd);
1221 1227 if (P->asfd >= 0)
1222 1228 (void) close(P->asfd);
1223 1229 if (P->statfd >= 0)
1224 1230 (void) close(P->statfd);
1225 1231 Preset_maps(P);
1226 1232 P->ops.pop_fini(P, P->data);
1227 1233
1228 1234 /* clear out the structure as a precaution against reuse */
1229 1235 (void) memset(P, 0, sizeof (*P));
1230 1236 P->ctlfd = -1;
1231 1237 P->asfd = -1;
1232 1238 P->statfd = -1;
1233 1239 P->agentctlfd = -1;
1234 1240 P->agentstatfd = -1;
1235 1241
1236 1242 free(P);
1237 1243 }
1238 1244
1239 1245 /*
1240 1246 * Return the state of the process, one of the PS_* values.
1241 1247 */
1242 1248 int
1243 1249 Pstate(struct ps_prochandle *P)
1244 1250 {
1245 1251 return (P->state);
1246 1252 }
1247 1253
1248 1254 /*
1249 1255 * Return the open address space file descriptor for the process.
1250 1256 * Clients must not close this file descriptor, not use it
1251 1257 * after the process is freed.
1252 1258 */
1253 1259 int
1254 1260 Pasfd(struct ps_prochandle *P)
1255 1261 {
1256 1262 return (P->asfd);
1257 1263 }
1258 1264
1259 1265 /*
1260 1266 * Return the open control file descriptor for the process.
1261 1267 * Clients must not close this file descriptor, not use it
1262 1268 * after the process is freed.
1263 1269 */
1264 1270 int
1265 1271 Pctlfd(struct ps_prochandle *P)
1266 1272 {
1267 1273 return (P->ctlfd);
1268 1274 }
1269 1275
1270 1276 /*
1271 1277 * Return a pointer to the process psinfo structure.
1272 1278 * Clients should not hold on to this pointer indefinitely.
1273 1279 * It will become invalid on Prelease().
1274 1280 */
1275 1281 const psinfo_t *
1276 1282 Ppsinfo(struct ps_prochandle *P)
1277 1283 {
1278 1284 return (P->ops.pop_psinfo(P, &P->psinfo, P->data));
1279 1285 }
1280 1286
1281 1287 /*
1282 1288 * Return a pointer to the process status structure.
1283 1289 * Clients should not hold on to this pointer indefinitely.
1284 1290 * It will become invalid on Prelease().
1285 1291 */
1286 1292 const pstatus_t *
1287 1293 Pstatus(struct ps_prochandle *P)
1288 1294 {
1289 1295 return (&P->status);
1290 1296 }
1291 1297
1292 1298 static void
1293 1299 Pread_status(struct ps_prochandle *P)
1294 1300 {
1295 1301 P->ops.pop_status(P, &P->status, P->data);
1296 1302 }
1297 1303
1298 1304 /*
1299 1305 * Fill in a pointer to a process credentials structure. The ngroups parameter
1300 1306 * is the number of supplementary group entries allocated in the caller's cred
1301 1307 * structure. It should equal zero or one unless extra space has been
1302 1308 * allocated for the group list by the caller.
1303 1309 */
1304 1310 int
1305 1311 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1306 1312 {
1307 1313 return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1308 1314 }
1309 1315
1310 1316 /* Return an allocated prsecflags_t */
1311 1317 int
1312 1318 Psecflags(struct ps_prochandle *P, prsecflags_t **psf)
1313 1319 {
1314 1320 int ret;
1315 1321
1316 1322 if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) {
1317 1323 if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) {
1318 1324 free(*psf);
1319 1325 *psf = NULL;
1320 1326 errno = EINVAL;
1321 1327 return (-1);
1322 1328 }
1323 1329 }
1324 1330
1325 1331 return (ret);
1326 1332 }
1327 1333
1328 1334 void
1329 1335 Psecflags_free(prsecflags_t *psf)
1330 1336 {
1331 1337 free(psf);
1332 1338 }
1333 1339
1334 1340 static prheader_t *
1335 1341 Plstatus(struct ps_prochandle *P)
1336 1342 {
1337 1343 return (P->ops.pop_lstatus(P, P->data));
1338 1344 }
1339 1345
1340 1346 static prheader_t *
1341 1347 Plpsinfo(struct ps_prochandle *P)
1342 1348 {
1343 1349 return (P->ops.pop_lpsinfo(P, P->data));
1344 1350 }
1345 1351
1346 1352
1347 1353 #if defined(__i386) || defined(__amd64)
1348 1354 /*
1349 1355 * Fill in a pointer to a process LDT structure.
1350 1356 * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1351 1357 * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1352 1358 * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1353 1359 */
1354 1360 int
1355 1361 Pldt(struct ps_prochandle *P, struct ssd *pldt, int nldt)
1356 1362 {
1357 1363 return (P->ops.pop_ldt(P, pldt, nldt, P->data));
1358 1364
1359 1365 }
1360 1366 #endif /* __i386 */
1361 1367
1362 1368 /* ARGSUSED */
1363 1369 void
1364 1370 Ppriv_free(struct ps_prochandle *P, prpriv_t *prv)
1365 1371 {
1366 1372 free(prv);
1367 1373 }
1368 1374
1369 1375 /*
1370 1376 * Return a malloced process privilege structure in *pprv.
1371 1377 */
1372 1378 int
1373 1379 Ppriv(struct ps_prochandle *P, prpriv_t **pprv)
1374 1380 {
1375 1381 return (P->ops.pop_priv(P, pprv, P->data));
1376 1382 }
1377 1383
1378 1384 int
1379 1385 Psetpriv(struct ps_prochandle *P, prpriv_t *pprv)
1380 1386 {
1381 1387 int rc;
1382 1388 long *ctl;
1383 1389 size_t sz;
1384 1390
1385 1391 if (P->state == PS_DEAD) {
1386 1392 errno = EBADF;
1387 1393 return (-1);
1388 1394 }
1389 1395
1390 1396 sz = PRIV_PRPRIV_SIZE(pprv) + sizeof (long);
1391 1397
1392 1398 sz = ((sz - 1) / sizeof (long) + 1) * sizeof (long);
1393 1399
1394 1400 ctl = malloc(sz);
1395 1401 if (ctl == NULL)
1396 1402 return (-1);
1397 1403
1398 1404 ctl[0] = PCSPRIV;
1399 1405
1400 1406 (void) memcpy(&ctl[1], pprv, PRIV_PRPRIV_SIZE(pprv));
1401 1407
1402 1408 if (write(P->ctlfd, ctl, sz) != sz)
1403 1409 rc = -1;
1404 1410 else
1405 1411 rc = 0;
1406 1412
1407 1413 free(ctl);
1408 1414
1409 1415 return (rc);
1410 1416 }
1411 1417
1412 1418 void *
1413 1419 Pprivinfo(struct ps_prochandle *P)
1414 1420 {
1415 1421 core_info_t *core = P->data;
1416 1422
1417 1423 /* Use default from libc */
1418 1424 if (P->state != PS_DEAD)
1419 1425 return (NULL);
1420 1426
1421 1427 return (core->core_privinfo);
1422 1428 }
1423 1429
1424 1430 /*
1425 1431 * Ensure that all cached state is written to the process.
1426 1432 * The cached state is the LWP's signal mask and registers
1427 1433 * and the process's tracing flags.
1428 1434 */
1429 1435 void
1430 1436 Psync(struct ps_prochandle *P)
1431 1437 {
1432 1438 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
1433 1439 long cmd[6];
1434 1440 iovec_t iov[12];
1435 1441 int n = 0;
1436 1442
1437 1443 if (P->flags & SETHOLD) {
1438 1444 cmd[0] = PCSHOLD;
1439 1445 iov[n].iov_base = (caddr_t)&cmd[0];
1440 1446 iov[n++].iov_len = sizeof (long);
1441 1447 iov[n].iov_base = (caddr_t)&P->status.pr_lwp.pr_lwphold;
1442 1448 iov[n++].iov_len = sizeof (P->status.pr_lwp.pr_lwphold);
1443 1449 }
1444 1450 if (P->flags & SETREGS) {
1445 1451 cmd[1] = PCSREG;
1446 1452 #ifdef __i386
1447 1453 /* XX64 we should probably restore REG_GS after this */
1448 1454 if (ctlfd == P->agentctlfd)
1449 1455 P->status.pr_lwp.pr_reg[GS] = 0;
1450 1456 #elif defined(__amd64)
1451 1457 /* XX64 */
1452 1458 #endif
1453 1459 iov[n].iov_base = (caddr_t)&cmd[1];
1454 1460 iov[n++].iov_len = sizeof (long);
1455 1461 iov[n].iov_base = (caddr_t)&P->status.pr_lwp.pr_reg[0];
1456 1462 iov[n++].iov_len = sizeof (P->status.pr_lwp.pr_reg);
1457 1463 }
1458 1464 if (P->flags & SETSIG) {
1459 1465 cmd[2] = PCSTRACE;
1460 1466 iov[n].iov_base = (caddr_t)&cmd[2];
1461 1467 iov[n++].iov_len = sizeof (long);
1462 1468 iov[n].iov_base = (caddr_t)&P->status.pr_sigtrace;
1463 1469 iov[n++].iov_len = sizeof (P->status.pr_sigtrace);
1464 1470 }
1465 1471 if (P->flags & SETFAULT) {
1466 1472 cmd[3] = PCSFAULT;
1467 1473 iov[n].iov_base = (caddr_t)&cmd[3];
1468 1474 iov[n++].iov_len = sizeof (long);
1469 1475 iov[n].iov_base = (caddr_t)&P->status.pr_flttrace;
1470 1476 iov[n++].iov_len = sizeof (P->status.pr_flttrace);
1471 1477 }
1472 1478 if (P->flags & SETENTRY) {
1473 1479 cmd[4] = PCSENTRY;
1474 1480 iov[n].iov_base = (caddr_t)&cmd[4];
1475 1481 iov[n++].iov_len = sizeof (long);
1476 1482 iov[n].iov_base = (caddr_t)&P->status.pr_sysentry;
1477 1483 iov[n++].iov_len = sizeof (P->status.pr_sysentry);
1478 1484 }
1479 1485 if (P->flags & SETEXIT) {
1480 1486 cmd[5] = PCSEXIT;
1481 1487 iov[n].iov_base = (caddr_t)&cmd[5];
1482 1488 iov[n++].iov_len = sizeof (long);
1483 1489 iov[n].iov_base = (caddr_t)&P->status.pr_sysexit;
1484 1490 iov[n++].iov_len = sizeof (P->status.pr_sysexit);
1485 1491 }
1486 1492
1487 1493 if (n == 0 || writev(ctlfd, iov, n) < 0)
1488 1494 return; /* nothing to do or write failed */
1489 1495
1490 1496 P->flags &= ~(SETSIG|SETFAULT|SETENTRY|SETEXIT|SETHOLD|SETREGS);
1491 1497 }
1492 1498
1493 1499 /*
1494 1500 * Reopen the /proc file (after PS_LOST).
1495 1501 */
1496 1502 int
1497 1503 Preopen(struct ps_prochandle *P)
1498 1504 {
1499 1505 int fd;
1500 1506 char procname[PATH_MAX];
1501 1507 char *fname;
1502 1508
1503 1509 if (P->state == PS_DEAD || P->state == PS_IDLE)
1504 1510 return (0);
1505 1511
1506 1512 if (P->agentcnt > 0) {
1507 1513 P->agentcnt = 1;
1508 1514 Pdestroy_agent(P);
1509 1515 }
1510 1516
1511 1517 (void) snprintf(procname, sizeof (procname), "%s/%d/",
1512 1518 procfs_path, (int)P->pid);
1513 1519 fname = procname + strlen(procname);
1514 1520
1515 1521 (void) strcpy(fname, "as");
1516 1522 if ((fd = open(procname, O_RDWR)) < 0 ||
1517 1523 close(P->asfd) < 0 ||
1518 1524 (fd = dupfd(fd, P->asfd)) != P->asfd) {
1519 1525 dprintf("Preopen: failed to open %s: %s\n",
1520 1526 procname, strerror(errno));
1521 1527 if (fd >= 0)
1522 1528 (void) close(fd);
1523 1529 return (-1);
1524 1530 }
1525 1531 P->asfd = fd;
1526 1532
1527 1533 (void) strcpy(fname, "status");
1528 1534 if ((fd = open(procname, O_RDONLY)) < 0 ||
1529 1535 close(P->statfd) < 0 ||
1530 1536 (fd = dupfd(fd, P->statfd)) != P->statfd) {
1531 1537 dprintf("Preopen: failed to open %s: %s\n",
1532 1538 procname, strerror(errno));
1533 1539 if (fd >= 0)
1534 1540 (void) close(fd);
1535 1541 return (-1);
1536 1542 }
1537 1543 P->statfd = fd;
1538 1544
1539 1545 (void) strcpy(fname, "ctl");
1540 1546 if ((fd = open(procname, O_WRONLY)) < 0 ||
1541 1547 close(P->ctlfd) < 0 ||
1542 1548 (fd = dupfd(fd, P->ctlfd)) != P->ctlfd) {
1543 1549 dprintf("Preopen: failed to open %s: %s\n",
1544 1550 procname, strerror(errno));
1545 1551 if (fd >= 0)
1546 1552 (void) close(fd);
1547 1553 return (-1);
1548 1554 }
1549 1555 P->ctlfd = fd;
1550 1556
1551 1557 /*
1552 1558 * Set the state to PS_RUN and wait for the process to stop so that
1553 1559 * we re-read the status from the new P->statfd. If this fails, Pwait
1554 1560 * will reset the state to PS_LOST and we fail the reopen. Before
1555 1561 * returning, we also forge a bit of P->status to allow the debugger to
1556 1562 * see that we are PS_LOST following a successful exec.
1557 1563 */
1558 1564 P->state = PS_RUN;
1559 1565 if (Pwait(P, 0) == -1) {
1560 1566 #ifdef _ILP32
1561 1567 if (errno == EOVERFLOW)
1562 1568 P->status.pr_dmodel = PR_MODEL_LP64;
1563 1569 #endif
1564 1570 P->status.pr_lwp.pr_why = PR_SYSEXIT;
1565 1571 P->status.pr_lwp.pr_what = SYS_execve;
1566 1572 P->status.pr_lwp.pr_errno = 0;
1567 1573 return (-1);
1568 1574 }
1569 1575
1570 1576 /*
1571 1577 * The process should be stopped on exec (REQUESTED)
1572 1578 * or else should be stopped on exit from exec() (SYSEXIT)
1573 1579 */
1574 1580 if (P->state == PS_STOP &&
1575 1581 (P->status.pr_lwp.pr_why == PR_REQUESTED ||
1576 1582 (P->status.pr_lwp.pr_why == PR_SYSEXIT &&
1577 1583 P->status.pr_lwp.pr_what == SYS_execve))) {
1578 1584 /* fake up stop-on-exit-from-execve */
1579 1585 if (P->status.pr_lwp.pr_why == PR_REQUESTED) {
1580 1586 P->status.pr_lwp.pr_why = PR_SYSEXIT;
1581 1587 P->status.pr_lwp.pr_what = SYS_execve;
1582 1588 P->status.pr_lwp.pr_errno = 0;
1583 1589 }
1584 1590 } else {
1585 1591 dprintf("Preopen: expected REQUESTED or "
1586 1592 "SYSEXIT(SYS_execve) stop\n");
1587 1593 }
1588 1594
1589 1595 return (0);
1590 1596 }
1591 1597
1592 1598 /*
1593 1599 * Define all settable flags other than the microstate accounting flags.
1594 1600 */
1595 1601 #define ALL_SETTABLE_FLAGS (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_PTRACE)
1596 1602
1597 1603 /*
1598 1604 * Restore /proc tracing flags to their original values
1599 1605 * in preparation for releasing the process.
1600 1606 * Also called by Pcreate() to clear all tracing flags.
1601 1607 */
1602 1608 static void
1603 1609 restore_tracing_flags(struct ps_prochandle *P)
1604 1610 {
1605 1611 long flags;
1606 1612 long cmd[4];
1607 1613 iovec_t iov[8];
1608 1614
1609 1615 if (P->flags & CREATED) {
1610 1616 /* we created this process; clear all tracing flags */
1611 1617 premptyset(&P->status.pr_sigtrace);
1612 1618 premptyset(&P->status.pr_flttrace);
1613 1619 premptyset(&P->status.pr_sysentry);
1614 1620 premptyset(&P->status.pr_sysexit);
1615 1621 if ((P->status.pr_flags & ALL_SETTABLE_FLAGS) != 0)
1616 1622 (void) Punsetflags(P, ALL_SETTABLE_FLAGS);
1617 1623 } else {
1618 1624 /* we grabbed the process; restore its tracing flags */
1619 1625 P->status.pr_sigtrace = P->orig_status.pr_sigtrace;
1620 1626 P->status.pr_flttrace = P->orig_status.pr_flttrace;
1621 1627 P->status.pr_sysentry = P->orig_status.pr_sysentry;
1622 1628 P->status.pr_sysexit = P->orig_status.pr_sysexit;
1623 1629 if ((P->status.pr_flags & ALL_SETTABLE_FLAGS) !=
1624 1630 (flags = (P->orig_status.pr_flags & ALL_SETTABLE_FLAGS))) {
1625 1631 (void) Punsetflags(P, ALL_SETTABLE_FLAGS);
1626 1632 if (flags)
1627 1633 (void) Psetflags(P, flags);
1628 1634 }
1629 1635 }
1630 1636
1631 1637 cmd[0] = PCSTRACE;
1632 1638 iov[0].iov_base = (caddr_t)&cmd[0];
1633 1639 iov[0].iov_len = sizeof (long);
1634 1640 iov[1].iov_base = (caddr_t)&P->status.pr_sigtrace;
1635 1641 iov[1].iov_len = sizeof (P->status.pr_sigtrace);
1636 1642
1637 1643 cmd[1] = PCSFAULT;
1638 1644 iov[2].iov_base = (caddr_t)&cmd[1];
1639 1645 iov[2].iov_len = sizeof (long);
1640 1646 iov[3].iov_base = (caddr_t)&P->status.pr_flttrace;
1641 1647 iov[3].iov_len = sizeof (P->status.pr_flttrace);
1642 1648
1643 1649 cmd[2] = PCSENTRY;
1644 1650 iov[4].iov_base = (caddr_t)&cmd[2];
1645 1651 iov[4].iov_len = sizeof (long);
1646 1652 iov[5].iov_base = (caddr_t)&P->status.pr_sysentry;
1647 1653 iov[5].iov_len = sizeof (P->status.pr_sysentry);
1648 1654
1649 1655 cmd[3] = PCSEXIT;
1650 1656 iov[6].iov_base = (caddr_t)&cmd[3];
1651 1657 iov[6].iov_len = sizeof (long);
1652 1658 iov[7].iov_base = (caddr_t)&P->status.pr_sysexit;
1653 1659 iov[7].iov_len = sizeof (P->status.pr_sysexit);
1654 1660
1655 1661 (void) writev(P->ctlfd, iov, 8);
1656 1662
1657 1663 P->flags &= ~(SETSIG|SETFAULT|SETENTRY|SETEXIT);
1658 1664 }
1659 1665
1660 1666 /*
1661 1667 * Release the process. Frees the process control structure.
1662 1668 * flags:
1663 1669 * PRELEASE_CLEAR Clear all tracing flags.
1664 1670 * PRELEASE_RETAIN Retain current tracing flags.
1665 1671 * PRELEASE_HANG Leave the process stopped and abandoned.
1666 1672 * PRELEASE_KILL Terminate the process with SIGKILL.
1667 1673 */
1668 1674 void
1669 1675 Prelease(struct ps_prochandle *P, int flags)
1670 1676 {
1671 1677 if (P->state == PS_DEAD) {
1672 1678 dprintf("Prelease: releasing handle %p PS_DEAD of pid %d\n",
1673 1679 (void *)P, (int)P->pid);
1674 1680 Pfree(P);
1675 1681 return;
1676 1682 }
1677 1683
1678 1684 if (P->state == PS_IDLE) {
1679 1685 file_info_t *fptr = list_head(&P->file_head);
1680 1686 dprintf("Prelease: releasing handle %p PS_IDLE of file %s\n",
1681 1687 (void *)P, fptr->file_pname);
1682 1688 Pfree(P);
1683 1689 return;
1684 1690 }
1685 1691
1686 1692 dprintf("Prelease: releasing handle %p pid %d\n",
1687 1693 (void *)P, (int)P->pid);
1688 1694
1689 1695 if (P->ctlfd == -1) {
1690 1696 Pfree(P);
1691 1697 return;
1692 1698 }
1693 1699
1694 1700 if (P->agentcnt > 0) {
1695 1701 P->agentcnt = 1;
1696 1702 Pdestroy_agent(P);
1697 1703 }
1698 1704
1699 1705 /*
1700 1706 * Attempt to stop the process.
1701 1707 */
1702 1708 P->state = PS_RUN;
1703 1709 (void) Pstop(P, 1000);
1704 1710
1705 1711 if (flags & PRELEASE_KILL) {
1706 1712 if (P->state == PS_STOP)
1707 1713 (void) Psetrun(P, SIGKILL, 0);
1708 1714 (void) kill(P->pid, SIGKILL);
1709 1715 Pfree(P);
1710 1716 return;
1711 1717 }
1712 1718
1713 1719 /*
1714 1720 * If we lost control, all we can do now is close the files.
1715 1721 * In this case, the last close sets the process running.
1716 1722 */
1717 1723 if (P->state != PS_STOP &&
1718 1724 (P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) == 0) {
1719 1725 Pfree(P);
1720 1726 return;
1721 1727 }
1722 1728
1723 1729 /*
1724 1730 * We didn't lose control; we do more.
1725 1731 */
1726 1732 Psync(P);
1727 1733
1728 1734 if (flags & PRELEASE_CLEAR)
1729 1735 P->flags |= CREATED;
1730 1736
1731 1737 if (!(flags & PRELEASE_RETAIN))
1732 1738 restore_tracing_flags(P);
1733 1739
1734 1740 if (flags & PRELEASE_HANG) {
1735 1741 /* Leave the process stopped and abandoned */
1736 1742 (void) Punsetflags(P, PR_RLC|PR_KLC);
1737 1743 Pfree(P);
1738 1744 return;
1739 1745 }
1740 1746
1741 1747 /*
1742 1748 * Set the process running if we created it or if it was
1743 1749 * not originally stopped or directed to stop via /proc
1744 1750 * or if we were given the PRELEASE_CLEAR flag.
1745 1751 */
1746 1752 if ((P->flags & CREATED) ||
1747 1753 (P->orig_status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) == 0) {
1748 1754 (void) Psetflags(P, PR_RLC);
1749 1755 /*
1750 1756 * We do this repeatedly because the process may have
1751 1757 * more than one LWP stopped on an event of interest.
1752 1758 * This makes sure all of them are set running.
1753 1759 */
1754 1760 do {
1755 1761 if (Psetrun(P, 0, 0) == -1 && errno == EBUSY)
1756 1762 break; /* Agent LWP may be stuck */
1757 1763 } while (Pstopstatus(P, PCNULL, 0) == 0 &&
1758 1764 P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP));
1759 1765
1760 1766 if (P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP))
1761 1767 dprintf("Prelease: failed to set process running\n");
1762 1768 }
1763 1769
1764 1770 Pfree(P);
1765 1771 }
1766 1772
1767 1773 /* debugging */
1768 1774 void
1769 1775 prldump(const char *caller, lwpstatus_t *lsp)
1770 1776 {
1771 1777 char name[32];
1772 1778 uint32_t bits;
1773 1779
1774 1780 switch (lsp->pr_why) {
1775 1781 case PR_REQUESTED:
1776 1782 dprintf("%s: REQUESTED\n", caller);
1777 1783 break;
1778 1784 case PR_SIGNALLED:
1779 1785 dprintf("%s: SIGNALLED %s\n", caller,
1780 1786 proc_signame(lsp->pr_what, name, sizeof (name)));
1781 1787 break;
1782 1788 case PR_FAULTED:
1783 1789 dprintf("%s: FAULTED %s\n", caller,
1784 1790 proc_fltname(lsp->pr_what, name, sizeof (name)));
1785 1791 break;
1786 1792 case PR_SYSENTRY:
1787 1793 dprintf("%s: SYSENTRY %s\n", caller,
1788 1794 proc_sysname(lsp->pr_what, name, sizeof (name)));
1789 1795 break;
1790 1796 case PR_SYSEXIT:
|
↓ open down ↓ |
1425 lines elided |
↑ open up ↑ |
1791 1797 dprintf("%s: SYSEXIT %s\n", caller,
1792 1798 proc_sysname(lsp->pr_what, name, sizeof (name)));
1793 1799 break;
1794 1800 case PR_JOBCONTROL:
1795 1801 dprintf("%s: JOBCONTROL %s\n", caller,
1796 1802 proc_signame(lsp->pr_what, name, sizeof (name)));
1797 1803 break;
1798 1804 case PR_SUSPENDED:
1799 1805 dprintf("%s: SUSPENDED\n", caller);
1800 1806 break;
1807 + case PR_BRAND:
1808 + dprintf("%s: BRANDPRIVATE (%d)\n", caller, lsp->pr_what);
1809 + break;
1801 1810 default:
1802 1811 dprintf("%s: Unknown\n", caller);
1803 1812 break;
1804 1813 }
1805 1814
1806 1815 if (lsp->pr_cursig)
1807 1816 dprintf("%s: p_cursig = %d\n", caller, lsp->pr_cursig);
1808 1817
1809 1818 bits = *((uint32_t *)&lsp->pr_lwppend);
1810 1819 if (bits)
1811 1820 dprintf("%s: pr_lwppend = 0x%.8X\n", caller, bits);
1812 1821 }
1813 1822
1814 1823 /* debugging */
1815 1824 static void
1816 1825 prdump(struct ps_prochandle *P)
1817 1826 {
1818 1827 uint32_t bits;
1819 1828
1820 1829 prldump("Pstopstatus", &P->status.pr_lwp);
1821 1830
1822 1831 bits = *((uint32_t *)&P->status.pr_sigpend);
1823 1832 if (bits)
1824 1833 dprintf("Pstopstatus: pr_sigpend = 0x%.8X\n", bits);
1825 1834 }
1826 1835
1827 1836 /*
1828 1837 * Wait for the specified process to stop or terminate.
1829 1838 * Or, just get the current status (PCNULL).
1830 1839 * Or, direct it to stop and get the current status (PCDSTOP).
1831 1840 * If the agent LWP exists, do these things to the agent,
1832 1841 * else do these things to the process as a whole.
1833 1842 */
1834 1843 int
1835 1844 Pstopstatus(struct ps_prochandle *P,
1836 1845 long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
1837 1846 uint_t msec) /* if non-zero, timeout in milliseconds */
1838 1847 {
1839 1848 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
1840 1849 long ctl[3];
1841 1850 ssize_t rc;
1842 1851 int err;
1843 1852 int old_state = P->state;
1844 1853
1845 1854 switch (P->state) {
1846 1855 case PS_RUN:
1847 1856 break;
1848 1857 case PS_STOP:
1849 1858 if (request != PCNULL && request != PCDSTOP)
1850 1859 return (0);
1851 1860 break;
1852 1861 case PS_LOST:
1853 1862 if (request != PCNULL) {
1854 1863 errno = EAGAIN;
1855 1864 return (-1);
1856 1865 }
1857 1866 break;
1858 1867 case PS_UNDEAD:
1859 1868 case PS_DEAD:
1860 1869 case PS_IDLE:
1861 1870 if (request != PCNULL) {
1862 1871 errno = ENOENT;
1863 1872 return (-1);
1864 1873 }
1865 1874 break;
1866 1875 default: /* corrupted state */
1867 1876 dprintf("Pstopstatus: corrupted state: %d\n", P->state);
1868 1877 errno = EINVAL;
1869 1878 return (-1);
1870 1879 }
1871 1880
1872 1881 ctl[0] = PCDSTOP;
1873 1882 ctl[1] = PCTWSTOP;
1874 1883 ctl[2] = (long)msec;
1875 1884 rc = 0;
1876 1885 switch (request) {
1877 1886 case PCSTOP:
1878 1887 rc = write(ctlfd, &ctl[0], 3*sizeof (long));
1879 1888 break;
1880 1889 case PCWSTOP:
1881 1890 rc = write(ctlfd, &ctl[1], 2*sizeof (long));
1882 1891 break;
1883 1892 case PCDSTOP:
1884 1893 rc = write(ctlfd, &ctl[0], 1*sizeof (long));
1885 1894 break;
1886 1895 case PCNULL:
1887 1896 if (P->state == PS_DEAD || P->state == PS_IDLE)
1888 1897 return (0);
1889 1898 break;
1890 1899 default: /* programming error */
1891 1900 errno = EINVAL;
1892 1901 return (-1);
1893 1902 }
1894 1903 err = (rc < 0)? errno : 0;
1895 1904 Psync(P);
1896 1905
1897 1906 if (P->agentstatfd < 0) {
1898 1907 if (pread(P->statfd, &P->status,
1899 1908 sizeof (P->status), (off_t)0) < 0)
1900 1909 err = errno;
1901 1910 } else {
1902 1911 if (pread(P->agentstatfd, &P->status.pr_lwp,
1903 1912 sizeof (P->status.pr_lwp), (off_t)0) < 0)
1904 1913 err = errno;
1905 1914 P->status.pr_flags = P->status.pr_lwp.pr_flags;
1906 1915 }
1907 1916
1908 1917 if (err) {
1909 1918 switch (err) {
1910 1919 case EINTR: /* user typed ctl-C */
1911 1920 case ERESTART:
1912 1921 dprintf("Pstopstatus: EINTR\n");
1913 1922 break;
1914 1923 case EAGAIN: /* we lost control of the the process */
1915 1924 case EOVERFLOW:
1916 1925 dprintf("Pstopstatus: PS_LOST, errno=%d\n", err);
1917 1926 P->state = PS_LOST;
1918 1927 break;
1919 1928 default: /* check for dead process */
1920 1929 if (_libproc_debug) {
1921 1930 const char *errstr;
1922 1931
1923 1932 switch (request) {
1924 1933 case PCNULL:
1925 1934 errstr = "Pstopstatus PCNULL"; break;
1926 1935 case PCSTOP:
1927 1936 errstr = "Pstopstatus PCSTOP"; break;
1928 1937 case PCDSTOP:
1929 1938 errstr = "Pstopstatus PCDSTOP"; break;
1930 1939 case PCWSTOP:
1931 1940 errstr = "Pstopstatus PCWSTOP"; break;
1932 1941 default:
1933 1942 errstr = "Pstopstatus PC???"; break;
1934 1943 }
1935 1944 dprintf("%s: %s\n", errstr, strerror(err));
1936 1945 }
1937 1946 deadcheck(P);
1938 1947 break;
1939 1948 }
1940 1949 if (err != EINTR && err != ERESTART) {
1941 1950 errno = err;
1942 1951 return (-1);
1943 1952 }
1944 1953 }
1945 1954
1946 1955 if (!(P->status.pr_flags & PR_STOPPED)) {
1947 1956 P->state = PS_RUN;
1948 1957 if (request == PCNULL || request == PCDSTOP || msec != 0)
1949 1958 return (0);
1950 1959 dprintf("Pstopstatus: process is not stopped\n");
1951 1960 errno = EPROTO;
1952 1961 return (-1);
1953 1962 }
1954 1963
1955 1964 P->state = PS_STOP;
1956 1965
1957 1966 if (_libproc_debug) /* debugging */
1958 1967 prdump(P);
1959 1968
1960 1969 /*
1961 1970 * If the process was already stopped coming into Pstopstatus(),
1962 1971 * then don't use its PC to set P->sysaddr since it may have been
1963 1972 * changed since the time the process originally stopped.
1964 1973 */
1965 1974 if (old_state == PS_STOP)
1966 1975 return (0);
1967 1976
1968 1977 switch (P->status.pr_lwp.pr_why) {
1969 1978 case PR_SYSENTRY:
|
↓ open down ↓ |
159 lines elided |
↑ open up ↑ |
1970 1979 case PR_SYSEXIT:
1971 1980 if (Pissyscall_prev(P, P->status.pr_lwp.pr_reg[R_PC],
1972 1981 &P->sysaddr) == 0)
1973 1982 P->sysaddr = P->status.pr_lwp.pr_reg[R_PC];
1974 1983 break;
1975 1984 case PR_REQUESTED:
1976 1985 case PR_SIGNALLED:
1977 1986 case PR_FAULTED:
1978 1987 case PR_JOBCONTROL:
1979 1988 case PR_SUSPENDED:
1989 + case PR_BRAND:
1980 1990 break;
1981 1991 default:
1982 1992 errno = EPROTO;
1983 1993 return (-1);
1984 1994 }
1985 1995
1986 1996 return (0);
1987 1997 }
1988 1998
1989 1999 /*
1990 2000 * Wait for the process to stop for any reason.
1991 2001 */
1992 2002 int
1993 2003 Pwait(struct ps_prochandle *P, uint_t msec)
1994 2004 {
1995 2005 return (Pstopstatus(P, PCWSTOP, msec));
1996 2006 }
1997 2007
1998 2008 /*
1999 2009 * Direct the process to stop; wait for it to stop.
2000 2010 */
2001 2011 int
2002 2012 Pstop(struct ps_prochandle *P, uint_t msec)
2003 2013 {
2004 2014 return (Pstopstatus(P, PCSTOP, msec));
2005 2015 }
2006 2016
2007 2017 /*
2008 2018 * Direct the process to stop; don't wait.
2009 2019 */
2010 2020 int
2011 2021 Pdstop(struct ps_prochandle *P)
2012 2022 {
2013 2023 return (Pstopstatus(P, PCDSTOP, 0));
2014 2024 }
2015 2025
2016 2026 static void
2017 2027 deadcheck(struct ps_prochandle *P)
2018 2028 {
2019 2029 int fd;
2020 2030 void *buf;
2021 2031 size_t size;
2022 2032
2023 2033 if (P->statfd < 0)
2024 2034 P->state = PS_UNDEAD;
2025 2035 else {
2026 2036 if (P->agentstatfd < 0) {
2027 2037 fd = P->statfd;
2028 2038 buf = &P->status;
2029 2039 size = sizeof (P->status);
2030 2040 } else {
2031 2041 fd = P->agentstatfd;
2032 2042 buf = &P->status.pr_lwp;
2033 2043 size = sizeof (P->status.pr_lwp);
2034 2044 }
2035 2045 while (pread(fd, buf, size, (off_t)0) != size) {
2036 2046 switch (errno) {
2037 2047 default:
2038 2048 P->state = PS_UNDEAD;
2039 2049 break;
2040 2050 case EINTR:
2041 2051 case ERESTART:
2042 2052 continue;
2043 2053 case EAGAIN:
2044 2054 P->state = PS_LOST;
2045 2055 break;
2046 2056 }
2047 2057 break;
2048 2058 }
2049 2059 P->status.pr_flags = P->status.pr_lwp.pr_flags;
2050 2060 }
2051 2061 }
2052 2062
2053 2063 /*
2054 2064 * Get the value of one register from stopped process.
2055 2065 */
2056 2066 int
2057 2067 Pgetareg(struct ps_prochandle *P, int regno, prgreg_t *preg)
2058 2068 {
2059 2069 if (regno < 0 || regno >= NPRGREG) {
2060 2070 errno = EINVAL;
2061 2071 return (-1);
2062 2072 }
2063 2073
2064 2074 if (P->state == PS_IDLE) {
2065 2075 errno = ENODATA;
2066 2076 return (-1);
2067 2077 }
2068 2078
2069 2079 if (P->state != PS_STOP && P->state != PS_DEAD) {
2070 2080 errno = EBUSY;
2071 2081 return (-1);
2072 2082 }
2073 2083
2074 2084 *preg = P->status.pr_lwp.pr_reg[regno];
2075 2085 return (0);
2076 2086 }
2077 2087
2078 2088 /*
2079 2089 * Put value of one register into stopped process.
2080 2090 */
2081 2091 int
2082 2092 Pputareg(struct ps_prochandle *P, int regno, prgreg_t reg)
2083 2093 {
2084 2094 if (regno < 0 || regno >= NPRGREG) {
2085 2095 errno = EINVAL;
2086 2096 return (-1);
2087 2097 }
2088 2098
2089 2099 if (P->state != PS_STOP) {
2090 2100 errno = EBUSY;
2091 2101 return (-1);
2092 2102 }
2093 2103
2094 2104 P->status.pr_lwp.pr_reg[regno] = reg;
2095 2105 P->flags |= SETREGS; /* set registers before continuing */
2096 2106 return (0);
2097 2107 }
2098 2108
2099 2109 int
2100 2110 Psetrun(struct ps_prochandle *P,
2101 2111 int sig, /* signal to pass to process */
2102 2112 int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
2103 2113 {
2104 2114 int ctlfd = (P->agentctlfd >= 0) ? P->agentctlfd : P->ctlfd;
2105 2115 int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP);
2106 2116
2107 2117 long ctl[1 + /* PCCFAULT */
2108 2118 1 + sizeof (siginfo_t)/sizeof (long) + /* PCSSIG/PCCSIG */
2109 2119 2 ]; /* PCRUN */
2110 2120
2111 2121 long *ctlp = ctl;
2112 2122 size_t size;
2113 2123
2114 2124 if (P->state != PS_STOP && (P->status.pr_lwp.pr_flags & sbits) == 0) {
2115 2125 errno = EBUSY;
2116 2126 return (-1);
2117 2127 }
2118 2128
2119 2129 Psync(P); /* flush tracing flags and registers */
2120 2130
2121 2131 if (flags & PRCFAULT) { /* clear current fault */
2122 2132 *ctlp++ = PCCFAULT;
2123 2133 flags &= ~PRCFAULT;
2124 2134 }
2125 2135
2126 2136 if (flags & PRCSIG) { /* clear current signal */
2127 2137 *ctlp++ = PCCSIG;
2128 2138 flags &= ~PRCSIG;
2129 2139 } else if (sig && sig != P->status.pr_lwp.pr_cursig) {
2130 2140 /* make current signal */
2131 2141 siginfo_t *infop;
2132 2142
2133 2143 *ctlp++ = PCSSIG;
2134 2144 infop = (siginfo_t *)ctlp;
2135 2145 (void) memset(infop, 0, sizeof (*infop));
2136 2146 infop->si_signo = sig;
2137 2147 ctlp += sizeof (siginfo_t) / sizeof (long);
2138 2148 }
2139 2149
2140 2150 *ctlp++ = PCRUN;
2141 2151 *ctlp++ = flags;
2142 2152 size = (char *)ctlp - (char *)ctl;
2143 2153
2144 2154 P->info_valid = 0; /* will need to update map and file info */
2145 2155
2146 2156 /*
2147 2157 * If we've cached ucontext-list information while we were stopped,
2148 2158 * free it now.
2149 2159 */
2150 2160 if (P->ucaddrs != NULL) {
2151 2161 free(P->ucaddrs);
2152 2162 P->ucaddrs = NULL;
2153 2163 P->ucnelems = 0;
2154 2164 }
2155 2165
2156 2166 if (write(ctlfd, ctl, size) != size) {
2157 2167 /* If it is dead or lost, return the real status, not PS_RUN */
2158 2168 if (errno == ENOENT || errno == EAGAIN) {
2159 2169 (void) Pstopstatus(P, PCNULL, 0);
2160 2170 return (0);
2161 2171 }
2162 2172 /* If it is not in a jobcontrol stop, issue an error message */
2163 2173 if (errno != EBUSY ||
2164 2174 P->status.pr_lwp.pr_why != PR_JOBCONTROL) {
2165 2175 dprintf("Psetrun: %s\n", strerror(errno));
2166 2176 return (-1);
2167 2177 }
2168 2178 /* Otherwise pretend that the job-stopped process is running */
2169 2179 }
2170 2180
2171 2181 P->state = PS_RUN;
2172 2182 return (0);
2173 2183 }
2174 2184
2175 2185 ssize_t
2176 2186 Pread(struct ps_prochandle *P,
2177 2187 void *buf, /* caller's buffer */
2178 2188 size_t nbyte, /* number of bytes to read */
2179 2189 uintptr_t address) /* address in process */
2180 2190 {
2181 2191 return (P->ops.pop_pread(P, buf, nbyte, address, P->data));
2182 2192 }
2183 2193
2184 2194 ssize_t
2185 2195 Pread_string(struct ps_prochandle *P,
2186 2196 char *buf, /* caller's buffer */
2187 2197 size_t size, /* upper limit on bytes to read */
2188 2198 uintptr_t addr) /* address in process */
2189 2199 {
2190 2200 enum { STRSZ = 40 };
2191 2201 char string[STRSZ + 1];
2192 2202 ssize_t leng = 0;
2193 2203 int nbyte;
2194 2204
2195 2205 if (size < 2) {
2196 2206 errno = EINVAL;
2197 2207 return (-1);
2198 2208 }
2199 2209
2200 2210 size--; /* ensure trailing null fits in buffer */
2201 2211
2202 2212 *buf = '\0';
2203 2213 string[STRSZ] = '\0';
2204 2214
2205 2215 for (nbyte = STRSZ; nbyte == STRSZ && leng < size; addr += STRSZ) {
2206 2216 if ((nbyte = P->ops.pop_pread(P, string, STRSZ, addr,
2207 2217 P->data)) <= 0) {
2208 2218 buf[leng] = '\0';
2209 2219 return (leng ? leng : -1);
2210 2220 }
2211 2221 if ((nbyte = strlen(string)) > 0) {
2212 2222 if (leng + nbyte > size)
2213 2223 nbyte = size - leng;
2214 2224 (void) strncpy(buf + leng, string, nbyte);
2215 2225 leng += nbyte;
2216 2226 }
2217 2227 }
2218 2228 buf[leng] = '\0';
2219 2229 return (leng);
2220 2230 }
2221 2231
2222 2232 ssize_t
2223 2233 Pwrite(struct ps_prochandle *P,
2224 2234 const void *buf, /* caller's buffer */
2225 2235 size_t nbyte, /* number of bytes to write */
2226 2236 uintptr_t address) /* address in process */
2227 2237 {
2228 2238 return (P->ops.pop_pwrite(P, buf, nbyte, address, P->data));
2229 2239 }
2230 2240
2231 2241 int
2232 2242 Pclearsig(struct ps_prochandle *P)
2233 2243 {
2234 2244 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2235 2245 long ctl = PCCSIG;
2236 2246
2237 2247 if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
2238 2248 return (-1);
2239 2249 P->status.pr_lwp.pr_cursig = 0;
2240 2250 return (0);
2241 2251 }
2242 2252
2243 2253 int
2244 2254 Pclearfault(struct ps_prochandle *P)
2245 2255 {
2246 2256 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2247 2257 long ctl = PCCFAULT;
2248 2258
2249 2259 if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
2250 2260 return (-1);
2251 2261 return (0);
2252 2262 }
2253 2263
2254 2264 /*
2255 2265 * Set a breakpoint trap, return original instruction.
2256 2266 */
2257 2267 int
2258 2268 Psetbkpt(struct ps_prochandle *P, uintptr_t address, ulong_t *saved)
2259 2269 {
2260 2270 long ctl[1 + sizeof (priovec_t) / sizeof (long) + /* PCREAD */
2261 2271 1 + sizeof (priovec_t) / sizeof (long)]; /* PCWRITE */
2262 2272 long *ctlp = ctl;
2263 2273 size_t size;
2264 2274 priovec_t *iovp;
2265 2275 instr_t bpt = BPT;
2266 2276 instr_t old;
2267 2277
2268 2278 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2269 2279 P->state == PS_IDLE) {
2270 2280 errno = ENOENT;
2271 2281 return (-1);
2272 2282 }
2273 2283
2274 2284 /* fetch the old instruction */
2275 2285 *ctlp++ = PCREAD;
2276 2286 iovp = (priovec_t *)ctlp;
2277 2287 iovp->pio_base = &old;
2278 2288 iovp->pio_len = sizeof (old);
2279 2289 iovp->pio_offset = address;
2280 2290 ctlp += sizeof (priovec_t) / sizeof (long);
2281 2291
2282 2292 /* write the BPT instruction */
2283 2293 *ctlp++ = PCWRITE;
2284 2294 iovp = (priovec_t *)ctlp;
2285 2295 iovp->pio_base = &bpt;
2286 2296 iovp->pio_len = sizeof (bpt);
2287 2297 iovp->pio_offset = address;
2288 2298 ctlp += sizeof (priovec_t) / sizeof (long);
2289 2299
2290 2300 size = (char *)ctlp - (char *)ctl;
2291 2301 if (write(P->ctlfd, ctl, size) != size)
2292 2302 return (-1);
2293 2303
2294 2304 /*
2295 2305 * Fail if there was already a breakpoint there from another debugger
2296 2306 * or DTrace's user-level tracing on x86.
2297 2307 */
2298 2308 if (old == BPT) {
2299 2309 errno = EBUSY;
2300 2310 return (-1);
2301 2311 }
2302 2312
2303 2313 *saved = (ulong_t)old;
2304 2314 return (0);
2305 2315 }
2306 2316
2307 2317 /*
2308 2318 * Restore original instruction where a breakpoint was set.
2309 2319 */
2310 2320 int
2311 2321 Pdelbkpt(struct ps_prochandle *P, uintptr_t address, ulong_t saved)
2312 2322 {
2313 2323 instr_t old = (instr_t)saved;
2314 2324 instr_t cur;
2315 2325
2316 2326 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2317 2327 P->state == PS_IDLE) {
2318 2328 errno = ENOENT;
2319 2329 return (-1);
2320 2330 }
2321 2331
2322 2332 /*
2323 2333 * If the breakpoint instruction we had placed has been overwritten
2324 2334 * with a new instruction, then don't try to replace it with the
2325 2335 * old instruction. Doing do can cause problems with self-modifying
2326 2336 * code -- PLTs for example. If the Pread() fails, we assume that we
2327 2337 * should proceed though most likely the Pwrite() will also fail.
2328 2338 */
2329 2339 if (Pread(P, &cur, sizeof (cur), address) == sizeof (cur) &&
2330 2340 cur != BPT)
2331 2341 return (0);
2332 2342
2333 2343 if (Pwrite(P, &old, sizeof (old), address) != sizeof (old))
2334 2344 return (-1);
2335 2345
2336 2346 return (0);
2337 2347 }
2338 2348
2339 2349 /*
2340 2350 * Common code for Pxecbkpt() and Lxecbkpt().
2341 2351 * Develop the array of requests that will do the job, then
2342 2352 * write them to the specified control file descriptor.
2343 2353 * Return the non-zero errno if the write fails.
2344 2354 */
2345 2355 static int
2346 2356 execute_bkpt(
2347 2357 int ctlfd, /* process or LWP control file descriptor */
2348 2358 const fltset_t *faultset, /* current set of traced faults */
2349 2359 const sigset_t *sigmask, /* current signal mask */
2350 2360 uintptr_t address, /* address of breakpint */
2351 2361 ulong_t saved) /* the saved instruction */
2352 2362 {
2353 2363 long ctl[
2354 2364 1 + sizeof (sigset_t) / sizeof (long) + /* PCSHOLD */
2355 2365 1 + sizeof (fltset_t) / sizeof (long) + /* PCSFAULT */
2356 2366 1 + sizeof (priovec_t) / sizeof (long) + /* PCWRITE */
2357 2367 2 + /* PCRUN */
2358 2368 1 + /* PCWSTOP */
2359 2369 1 + /* PCCFAULT */
2360 2370 1 + sizeof (priovec_t) / sizeof (long) + /* PCWRITE */
2361 2371 1 + sizeof (fltset_t) / sizeof (long) + /* PCSFAULT */
2362 2372 1 + sizeof (sigset_t) / sizeof (long)]; /* PCSHOLD */
2363 2373 long *ctlp = ctl;
2364 2374 sigset_t unblock;
2365 2375 size_t size;
2366 2376 ssize_t ssize;
2367 2377 priovec_t *iovp;
2368 2378 sigset_t *holdp;
2369 2379 fltset_t *faultp;
2370 2380 instr_t old = (instr_t)saved;
2371 2381 instr_t bpt = BPT;
2372 2382 int error = 0;
2373 2383
2374 2384 /* block our signals for the duration */
2375 2385 (void) sigprocmask(SIG_BLOCK, &blockable_sigs, &unblock);
2376 2386
2377 2387 /* hold posted signals */
2378 2388 *ctlp++ = PCSHOLD;
2379 2389 holdp = (sigset_t *)ctlp;
2380 2390 prfillset(holdp);
2381 2391 prdelset(holdp, SIGKILL);
2382 2392 prdelset(holdp, SIGSTOP);
2383 2393 ctlp += sizeof (sigset_t) / sizeof (long);
2384 2394
2385 2395 /* force tracing of FLTTRACE */
2386 2396 if (!(prismember(faultset, FLTTRACE))) {
2387 2397 *ctlp++ = PCSFAULT;
2388 2398 faultp = (fltset_t *)ctlp;
2389 2399 *faultp = *faultset;
2390 2400 praddset(faultp, FLTTRACE);
2391 2401 ctlp += sizeof (fltset_t) / sizeof (long);
2392 2402 }
2393 2403
2394 2404 /* restore the old instruction */
2395 2405 *ctlp++ = PCWRITE;
2396 2406 iovp = (priovec_t *)ctlp;
2397 2407 iovp->pio_base = &old;
2398 2408 iovp->pio_len = sizeof (old);
2399 2409 iovp->pio_offset = address;
2400 2410 ctlp += sizeof (priovec_t) / sizeof (long);
2401 2411
2402 2412 /* clear current signal and fault; set running w/ single-step */
2403 2413 *ctlp++ = PCRUN;
2404 2414 *ctlp++ = PRCSIG | PRCFAULT | PRSTEP;
2405 2415
2406 2416 /* wait for stop, cancel the fault */
2407 2417 *ctlp++ = PCWSTOP;
2408 2418 *ctlp++ = PCCFAULT;
2409 2419
2410 2420 /* restore the breakpoint trap */
2411 2421 *ctlp++ = PCWRITE;
2412 2422 iovp = (priovec_t *)ctlp;
2413 2423 iovp->pio_base = &bpt;
2414 2424 iovp->pio_len = sizeof (bpt);
2415 2425 iovp->pio_offset = address;
2416 2426 ctlp += sizeof (priovec_t) / sizeof (long);
2417 2427
2418 2428 /* restore fault tracing set */
2419 2429 if (!(prismember(faultset, FLTTRACE))) {
2420 2430 *ctlp++ = PCSFAULT;
2421 2431 *(fltset_t *)ctlp = *faultset;
2422 2432 ctlp += sizeof (fltset_t) / sizeof (long);
2423 2433 }
2424 2434
2425 2435 /* restore the hold mask */
2426 2436 *ctlp++ = PCSHOLD;
2427 2437 *(sigset_t *)ctlp = *sigmask;
2428 2438 ctlp += sizeof (sigset_t) / sizeof (long);
2429 2439
2430 2440 size = (char *)ctlp - (char *)ctl;
2431 2441 if ((ssize = write(ctlfd, ctl, size)) != size)
2432 2442 error = (ssize == -1)? errno : EINTR;
2433 2443 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2434 2444 return (error);
2435 2445 }
2436 2446
2437 2447 /*
2438 2448 * Step over a breakpoint, i.e., execute the instruction that
2439 2449 * really belongs at the breakpoint location (the current %pc)
2440 2450 * and leave the process stopped at the next instruction.
2441 2451 */
2442 2452 int
2443 2453 Pxecbkpt(struct ps_prochandle *P, ulong_t saved)
2444 2454 {
2445 2455 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2446 2456 int rv, error;
2447 2457
2448 2458 if (P->state != PS_STOP) {
2449 2459 errno = EBUSY;
2450 2460 return (-1);
2451 2461 }
2452 2462
2453 2463 Psync(P);
2454 2464
2455 2465 error = execute_bkpt(ctlfd,
2456 2466 &P->status.pr_flttrace, &P->status.pr_lwp.pr_lwphold,
2457 2467 P->status.pr_lwp.pr_reg[R_PC], saved);
2458 2468 rv = Pstopstatus(P, PCNULL, 0);
2459 2469
2460 2470 if (error != 0) {
2461 2471 if (P->status.pr_lwp.pr_why == PR_JOBCONTROL &&
2462 2472 error == EBUSY) { /* jobcontrol stop -- back off */
2463 2473 P->state = PS_RUN;
2464 2474 return (0);
2465 2475 }
2466 2476 if (error == ENOENT)
2467 2477 return (0);
2468 2478 errno = error;
2469 2479 return (-1);
2470 2480 }
2471 2481
2472 2482 return (rv);
2473 2483 }
2474 2484
2475 2485 /*
2476 2486 * Install the watchpoint described by wp.
2477 2487 */
2478 2488 int
2479 2489 Psetwapt(struct ps_prochandle *P, const prwatch_t *wp)
2480 2490 {
2481 2491 long ctl[1 + sizeof (prwatch_t) / sizeof (long)];
2482 2492 prwatch_t *cwp = (prwatch_t *)&ctl[1];
2483 2493
2484 2494 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2485 2495 P->state == PS_IDLE) {
2486 2496 errno = ENOENT;
2487 2497 return (-1);
2488 2498 }
2489 2499
2490 2500 ctl[0] = PCWATCH;
2491 2501 cwp->pr_vaddr = wp->pr_vaddr;
2492 2502 cwp->pr_size = wp->pr_size;
2493 2503 cwp->pr_wflags = wp->pr_wflags;
2494 2504
2495 2505 if (write(P->ctlfd, ctl, sizeof (ctl)) != sizeof (ctl))
2496 2506 return (-1);
2497 2507
2498 2508 return (0);
2499 2509 }
2500 2510
2501 2511 /*
2502 2512 * Remove the watchpoint described by wp.
2503 2513 */
2504 2514 int
2505 2515 Pdelwapt(struct ps_prochandle *P, const prwatch_t *wp)
2506 2516 {
2507 2517 long ctl[1 + sizeof (prwatch_t) / sizeof (long)];
2508 2518 prwatch_t *cwp = (prwatch_t *)&ctl[1];
2509 2519
2510 2520 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2511 2521 P->state == PS_IDLE) {
2512 2522 errno = ENOENT;
2513 2523 return (-1);
2514 2524 }
2515 2525
2516 2526 ctl[0] = PCWATCH;
2517 2527 cwp->pr_vaddr = wp->pr_vaddr;
2518 2528 cwp->pr_size = wp->pr_size;
2519 2529 cwp->pr_wflags = 0;
2520 2530
2521 2531 if (write(P->ctlfd, ctl, sizeof (ctl)) != sizeof (ctl))
2522 2532 return (-1);
2523 2533
2524 2534 return (0);
2525 2535 }
2526 2536
2527 2537 /*
2528 2538 * Common code for Pxecwapt() and Lxecwapt(). Develop the array of requests
2529 2539 * that will do the job, then write them to the specified control file
2530 2540 * descriptor. Return the non-zero errno if the write fails.
2531 2541 */
2532 2542 static int
2533 2543 execute_wapt(
2534 2544 int ctlfd, /* process or LWP control file descriptor */
2535 2545 const fltset_t *faultset, /* current set of traced faults */
2536 2546 const sigset_t *sigmask, /* current signal mask */
2537 2547 const prwatch_t *wp) /* watchpoint descriptor */
2538 2548 {
2539 2549 long ctl[
2540 2550 1 + sizeof (sigset_t) / sizeof (long) + /* PCSHOLD */
2541 2551 1 + sizeof (fltset_t) / sizeof (long) + /* PCSFAULT */
2542 2552 1 + sizeof (prwatch_t) / sizeof (long) + /* PCWATCH */
2543 2553 2 + /* PCRUN */
2544 2554 1 + /* PCWSTOP */
2545 2555 1 + /* PCCFAULT */
2546 2556 1 + sizeof (prwatch_t) / sizeof (long) + /* PCWATCH */
2547 2557 1 + sizeof (fltset_t) / sizeof (long) + /* PCSFAULT */
2548 2558 1 + sizeof (sigset_t) / sizeof (long)]; /* PCSHOLD */
2549 2559
2550 2560 long *ctlp = ctl;
2551 2561 int error = 0;
2552 2562
2553 2563 sigset_t unblock;
2554 2564 sigset_t *holdp;
2555 2565 fltset_t *faultp;
2556 2566 prwatch_t *prw;
2557 2567 ssize_t ssize;
2558 2568 size_t size;
2559 2569
2560 2570 (void) sigprocmask(SIG_BLOCK, &blockable_sigs, &unblock);
2561 2571
2562 2572 /*
2563 2573 * Hold all posted signals in the victim process prior to stepping.
2564 2574 */
2565 2575 *ctlp++ = PCSHOLD;
2566 2576 holdp = (sigset_t *)ctlp;
2567 2577 prfillset(holdp);
2568 2578 prdelset(holdp, SIGKILL);
2569 2579 prdelset(holdp, SIGSTOP);
2570 2580 ctlp += sizeof (sigset_t) / sizeof (long);
2571 2581
2572 2582 /*
2573 2583 * Force tracing of FLTTRACE since we need to single step.
2574 2584 */
2575 2585 if (!(prismember(faultset, FLTTRACE))) {
2576 2586 *ctlp++ = PCSFAULT;
2577 2587 faultp = (fltset_t *)ctlp;
2578 2588 *faultp = *faultset;
2579 2589 praddset(faultp, FLTTRACE);
2580 2590 ctlp += sizeof (fltset_t) / sizeof (long);
2581 2591 }
2582 2592
2583 2593 /*
2584 2594 * Clear only the current watchpoint by setting pr_wflags to zero.
2585 2595 */
2586 2596 *ctlp++ = PCWATCH;
2587 2597 prw = (prwatch_t *)ctlp;
2588 2598 prw->pr_vaddr = wp->pr_vaddr;
2589 2599 prw->pr_size = wp->pr_size;
2590 2600 prw->pr_wflags = 0;
2591 2601 ctlp += sizeof (prwatch_t) / sizeof (long);
2592 2602
2593 2603 /*
2594 2604 * Clear the current signal and fault; set running with single-step.
2595 2605 * Then wait for the victim to stop and cancel the FLTTRACE.
2596 2606 */
2597 2607 *ctlp++ = PCRUN;
2598 2608 *ctlp++ = PRCSIG | PRCFAULT | PRSTEP;
2599 2609 *ctlp++ = PCWSTOP;
2600 2610 *ctlp++ = PCCFAULT;
2601 2611
2602 2612 /*
2603 2613 * Restore the current watchpoint.
2604 2614 */
2605 2615 *ctlp++ = PCWATCH;
2606 2616 (void) memcpy(ctlp, wp, sizeof (prwatch_t));
2607 2617 ctlp += sizeof (prwatch_t) / sizeof (long);
2608 2618
2609 2619 /*
2610 2620 * Restore fault tracing set if we modified it.
2611 2621 */
2612 2622 if (!(prismember(faultset, FLTTRACE))) {
2613 2623 *ctlp++ = PCSFAULT;
2614 2624 *(fltset_t *)ctlp = *faultset;
2615 2625 ctlp += sizeof (fltset_t) / sizeof (long);
2616 2626 }
2617 2627
2618 2628 /*
2619 2629 * Restore the hold mask to the current hold mask (i.e. the one
2620 2630 * before we executed any of the previous operations).
2621 2631 */
2622 2632 *ctlp++ = PCSHOLD;
2623 2633 *(sigset_t *)ctlp = *sigmask;
2624 2634 ctlp += sizeof (sigset_t) / sizeof (long);
2625 2635
2626 2636 size = (char *)ctlp - (char *)ctl;
2627 2637 if ((ssize = write(ctlfd, ctl, size)) != size)
2628 2638 error = (ssize == -1)? errno : EINTR;
2629 2639 (void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2630 2640 return (error);
2631 2641 }
2632 2642
2633 2643 /*
2634 2644 * Step over a watchpoint, i.e., execute the instruction that was stopped by
2635 2645 * the watchpoint, and then leave the LWP stopped at the next instruction.
2636 2646 */
2637 2647 int
2638 2648 Pxecwapt(struct ps_prochandle *P, const prwatch_t *wp)
2639 2649 {
2640 2650 int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2641 2651 int rv, error;
2642 2652
2643 2653 if (P->state != PS_STOP) {
2644 2654 errno = EBUSY;
2645 2655 return (-1);
2646 2656 }
2647 2657
2648 2658 Psync(P);
2649 2659 error = execute_wapt(ctlfd,
2650 2660 &P->status.pr_flttrace, &P->status.pr_lwp.pr_lwphold, wp);
2651 2661 rv = Pstopstatus(P, PCNULL, 0);
2652 2662
2653 2663 if (error != 0) {
2654 2664 if (P->status.pr_lwp.pr_why == PR_JOBCONTROL &&
2655 2665 error == EBUSY) { /* jobcontrol stop -- back off */
2656 2666 P->state = PS_RUN;
2657 2667 return (0);
2658 2668 }
2659 2669 if (error == ENOENT)
2660 2670 return (0);
2661 2671 errno = error;
2662 2672 return (-1);
2663 2673 }
2664 2674
2665 2675 return (rv);
2666 2676 }
2667 2677
2668 2678 int
2669 2679 Psetflags(struct ps_prochandle *P, long flags)
2670 2680 {
2671 2681 int rc;
2672 2682 long ctl[2];
2673 2683
2674 2684 ctl[0] = PCSET;
2675 2685 ctl[1] = flags;
2676 2686
2677 2687 if (write(P->ctlfd, ctl, 2*sizeof (long)) != 2*sizeof (long)) {
2678 2688 rc = -1;
2679 2689 } else {
2680 2690 P->status.pr_flags |= flags;
2681 2691 P->status.pr_lwp.pr_flags |= flags;
2682 2692 rc = 0;
2683 2693 }
2684 2694
2685 2695 return (rc);
2686 2696 }
2687 2697
2688 2698 int
2689 2699 Punsetflags(struct ps_prochandle *P, long flags)
2690 2700 {
2691 2701 int rc;
2692 2702 long ctl[2];
2693 2703
2694 2704 ctl[0] = PCUNSET;
2695 2705 ctl[1] = flags;
2696 2706
2697 2707 if (write(P->ctlfd, ctl, 2*sizeof (long)) != 2*sizeof (long)) {
2698 2708 rc = -1;
2699 2709 } else {
2700 2710 P->status.pr_flags &= ~flags;
2701 2711 P->status.pr_lwp.pr_flags &= ~flags;
2702 2712 rc = 0;
2703 2713 }
2704 2714
2705 2715 return (rc);
2706 2716 }
2707 2717
2708 2718 /*
2709 2719 * Common function to allow clients to manipulate the action to be taken
2710 2720 * on receipt of a signal, receipt of machine fault, entry to a system call,
2711 2721 * or exit from a system call. We make use of our private prset_* functions
2712 2722 * in order to make this code be common. The 'which' parameter identifies
2713 2723 * the code for the event of interest (0 means change the entire set), and
2714 2724 * the 'stop' parameter is a boolean indicating whether the process should
2715 2725 * stop when the event of interest occurs. The previous value is returned
2716 2726 * to the caller; -1 is returned if an error occurred.
2717 2727 */
2718 2728 static int
2719 2729 Psetaction(struct ps_prochandle *P, void *sp, size_t size,
2720 2730 uint_t flag, int max, int which, int stop)
2721 2731 {
2722 2732 int oldval;
2723 2733
2724 2734 if (which < 0 || which > max) {
2725 2735 errno = EINVAL;
2726 2736 return (-1);
2727 2737 }
2728 2738
2729 2739 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2730 2740 P->state == PS_IDLE) {
2731 2741 errno = ENOENT;
2732 2742 return (-1);
2733 2743 }
2734 2744
2735 2745 oldval = prset_ismember(sp, size, which) ? TRUE : FALSE;
2736 2746
2737 2747 if (stop) {
2738 2748 if (which == 0) {
2739 2749 prset_fill(sp, size);
2740 2750 P->flags |= flag;
2741 2751 } else if (!oldval) {
2742 2752 prset_add(sp, size, which);
2743 2753 P->flags |= flag;
2744 2754 }
2745 2755 } else {
2746 2756 if (which == 0) {
2747 2757 prset_empty(sp, size);
2748 2758 P->flags |= flag;
2749 2759 } else if (oldval) {
2750 2760 prset_del(sp, size, which);
2751 2761 P->flags |= flag;
2752 2762 }
2753 2763 }
2754 2764
2755 2765 if (P->state == PS_RUN)
2756 2766 Psync(P);
2757 2767
2758 2768 return (oldval);
2759 2769 }
2760 2770
2761 2771 /*
2762 2772 * Set action on specified signal.
2763 2773 */
2764 2774 int
2765 2775 Psignal(struct ps_prochandle *P, int which, int stop)
2766 2776 {
2767 2777 int oldval;
2768 2778
2769 2779 if (which == SIGKILL && stop != 0) {
2770 2780 errno = EINVAL;
2771 2781 return (-1);
2772 2782 }
2773 2783
2774 2784 oldval = Psetaction(P, &P->status.pr_sigtrace, sizeof (sigset_t),
2775 2785 SETSIG, PRMAXSIG, which, stop);
2776 2786
2777 2787 if (oldval != -1 && which == 0 && stop != 0)
2778 2788 prdelset(&P->status.pr_sigtrace, SIGKILL);
2779 2789
2780 2790 return (oldval);
2781 2791 }
2782 2792
2783 2793 /*
2784 2794 * Set all signal tracing flags.
2785 2795 */
2786 2796 void
2787 2797 Psetsignal(struct ps_prochandle *P, const sigset_t *set)
2788 2798 {
2789 2799 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2790 2800 P->state == PS_IDLE)
2791 2801 return;
2792 2802
2793 2803 P->status.pr_sigtrace = *set;
2794 2804 P->flags |= SETSIG;
2795 2805
2796 2806 if (P->state == PS_RUN)
2797 2807 Psync(P);
2798 2808 }
2799 2809
2800 2810 /*
2801 2811 * Set action on specified fault.
2802 2812 */
2803 2813 int
2804 2814 Pfault(struct ps_prochandle *P, int which, int stop)
2805 2815 {
2806 2816 return (Psetaction(P, &P->status.pr_flttrace, sizeof (fltset_t),
2807 2817 SETFAULT, PRMAXFAULT, which, stop));
2808 2818 }
2809 2819
2810 2820 /*
2811 2821 * Set all machine fault tracing flags.
2812 2822 */
2813 2823 void
2814 2824 Psetfault(struct ps_prochandle *P, const fltset_t *set)
2815 2825 {
2816 2826 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2817 2827 P->state == PS_IDLE)
2818 2828 return;
2819 2829
2820 2830 P->status.pr_flttrace = *set;
2821 2831 P->flags |= SETFAULT;
2822 2832
2823 2833 if (P->state == PS_RUN)
2824 2834 Psync(P);
2825 2835 }
2826 2836
2827 2837 /*
2828 2838 * Set action on specified system call entry.
2829 2839 */
2830 2840 int
2831 2841 Psysentry(struct ps_prochandle *P, int which, int stop)
2832 2842 {
2833 2843 return (Psetaction(P, &P->status.pr_sysentry, sizeof (sysset_t),
2834 2844 SETENTRY, PRMAXSYS, which, stop));
2835 2845 }
2836 2846
2837 2847 /*
2838 2848 * Set all system call entry tracing flags.
2839 2849 */
2840 2850 void
2841 2851 Psetsysentry(struct ps_prochandle *P, const sysset_t *set)
2842 2852 {
2843 2853 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2844 2854 P->state == PS_IDLE)
2845 2855 return;
2846 2856
2847 2857 P->status.pr_sysentry = *set;
2848 2858 P->flags |= SETENTRY;
2849 2859
2850 2860 if (P->state == PS_RUN)
2851 2861 Psync(P);
2852 2862 }
2853 2863
2854 2864 /*
2855 2865 * Set action on specified system call exit.
2856 2866 */
2857 2867 int
2858 2868 Psysexit(struct ps_prochandle *P, int which, int stop)
2859 2869 {
2860 2870 return (Psetaction(P, &P->status.pr_sysexit, sizeof (sysset_t),
2861 2871 SETEXIT, PRMAXSYS, which, stop));
2862 2872 }
2863 2873
2864 2874 /*
2865 2875 * Set all system call exit tracing flags.
2866 2876 */
2867 2877 void
2868 2878 Psetsysexit(struct ps_prochandle *P, const sysset_t *set)
2869 2879 {
2870 2880 if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2871 2881 P->state == PS_IDLE)
2872 2882 return;
2873 2883
2874 2884 P->status.pr_sysexit = *set;
2875 2885 P->flags |= SETEXIT;
2876 2886
2877 2887 if (P->state == PS_RUN)
2878 2888 Psync(P);
2879 2889 }
2880 2890
2881 2891 /*
2882 2892 * Utility function to read the contents of a file that contains a
2883 2893 * prheader_t at the start (/proc/pid/lstatus or /proc/pid/lpsinfo).
2884 2894 * Returns a malloc()d buffer or NULL on failure.
2885 2895 */
2886 2896 static prheader_t *
2887 2897 read_lfile(struct ps_prochandle *P, const char *lname)
2888 2898 {
2889 2899 prheader_t *Lhp;
2890 2900 char lpath[PATH_MAX];
2891 2901 struct stat64 statb;
2892 2902 int fd;
2893 2903 size_t size;
2894 2904 ssize_t rval;
2895 2905
2896 2906 (void) snprintf(lpath, sizeof (lpath), "%s/%d/%s", procfs_path,
2897 2907 (int)P->status.pr_pid, lname);
2898 2908 if ((fd = open(lpath, O_RDONLY)) < 0 || fstat64(fd, &statb) != 0) {
2899 2909 if (fd >= 0)
2900 2910 (void) close(fd);
2901 2911 return (NULL);
2902 2912 }
2903 2913
2904 2914 /*
2905 2915 * 'size' is just the initial guess at the buffer size.
2906 2916 * It will have to grow if the number of lwps increases
2907 2917 * while we are looking at the process.
2908 2918 * 'size' must be larger than the actual file size.
2909 2919 */
2910 2920 size = statb.st_size + 32;
2911 2921
2912 2922 for (;;) {
2913 2923 if ((Lhp = malloc(size)) == NULL)
2914 2924 break;
2915 2925 if ((rval = pread(fd, Lhp, size, 0)) < 0 ||
2916 2926 rval <= sizeof (prheader_t)) {
2917 2927 free(Lhp);
2918 2928 Lhp = NULL;
2919 2929 break;
2920 2930 }
2921 2931 if (rval < size)
2922 2932 break;
2923 2933 /* need a bigger buffer */
2924 2934 free(Lhp);
2925 2935 size *= 2;
2926 2936 }
2927 2937
2928 2938 (void) close(fd);
2929 2939 return (Lhp);
2930 2940 }
2931 2941
2932 2942 /*
2933 2943 * LWP iteration interface.
2934 2944 */
2935 2945 int
2936 2946 Plwp_iter(struct ps_prochandle *P, proc_lwp_f *func, void *cd)
2937 2947 {
2938 2948 prheader_t *Lhp;
2939 2949 lwpstatus_t *Lsp;
2940 2950 long nlwp;
2941 2951 int rv;
2942 2952
2943 2953 switch (P->state) {
2944 2954 case PS_RUN:
2945 2955 (void) Pstopstatus(P, PCNULL, 0);
2946 2956 break;
2947 2957
2948 2958 case PS_STOP:
2949 2959 Psync(P);
2950 2960 break;
2951 2961
2952 2962 case PS_IDLE:
2953 2963 errno = ENODATA;
2954 2964 return (-1);
2955 2965 }
2956 2966
2957 2967 /*
2958 2968 * For either live processes or cores, the single LWP case is easy:
2959 2969 * the pstatus_t contains the lwpstatus_t for the only LWP.
2960 2970 */
2961 2971 if (P->status.pr_nlwp <= 1)
2962 2972 return (func(cd, &P->status.pr_lwp));
2963 2973
2964 2974 /*
2965 2975 * For the core file multi-LWP case, we just iterate through the
2966 2976 * list of LWP structs we read in from the core file.
2967 2977 */
2968 2978 if (P->state == PS_DEAD) {
2969 2979 core_info_t *core = P->data;
2970 2980 lwp_info_t *lwp;
2971 2981
2972 2982 for (lwp = list_tail(&core->core_lwp_head); lwp != NULL;
2973 2983 lwp = list_prev(&core->core_lwp_head, lwp)) {
2974 2984 if (lwp->lwp_psinfo.pr_sname != 'Z' &&
2975 2985 (rv = func(cd, &lwp->lwp_status)) != 0)
2976 2986 break;
2977 2987 }
2978 2988
2979 2989 return (rv);
2980 2990 }
2981 2991
2982 2992 /*
2983 2993 * For the live process multi-LWP case, we have to work a little
2984 2994 * harder: the /proc/pid/lstatus file has the array of LWP structs.
2985 2995 */
2986 2996 if ((Lhp = Plstatus(P)) == NULL)
2987 2997 return (-1);
2988 2998
2989 2999 for (nlwp = Lhp->pr_nent, Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
2990 3000 nlwp > 0;
2991 3001 nlwp--, Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize)) {
2992 3002 if ((rv = func(cd, Lsp)) != 0)
2993 3003 break;
2994 3004 }
2995 3005
2996 3006 free(Lhp);
2997 3007 return (rv);
2998 3008 }
2999 3009
3000 3010 /*
3001 3011 * Extended LWP iteration interface.
3002 3012 * Iterate over all LWPs, active and zombie.
3003 3013 */
3004 3014 int
3005 3015 Plwp_iter_all(struct ps_prochandle *P, proc_lwp_all_f *func, void *cd)
3006 3016 {
3007 3017 prheader_t *Lhp = NULL;
3008 3018 lwpstatus_t *Lsp;
3009 3019 lwpstatus_t *sp;
3010 3020 prheader_t *Lphp = NULL;
3011 3021 lwpsinfo_t *Lpsp;
3012 3022 long nstat;
3013 3023 long ninfo;
3014 3024 int rv;
3015 3025
3016 3026 retry:
3017 3027 if (Lhp != NULL)
3018 3028 free(Lhp);
3019 3029 if (Lphp != NULL)
3020 3030 free(Lphp);
3021 3031 if (P->state == PS_RUN)
3022 3032 (void) Pstopstatus(P, PCNULL, 0);
3023 3033 (void) Ppsinfo(P);
3024 3034
3025 3035 if (P->state == PS_STOP)
3026 3036 Psync(P);
3027 3037
3028 3038 /*
3029 3039 * For either live processes or cores, the single LWP case is easy:
3030 3040 * the pstatus_t contains the lwpstatus_t for the only LWP and
3031 3041 * the psinfo_t contains the lwpsinfo_t for the only LWP.
3032 3042 */
3033 3043 if (P->status.pr_nlwp + P->status.pr_nzomb <= 1)
3034 3044 return (func(cd, &P->status.pr_lwp, &P->psinfo.pr_lwp));
3035 3045
3036 3046 /*
3037 3047 * For the core file multi-LWP case, we just iterate through the
3038 3048 * list of LWP structs we read in from the core file.
3039 3049 */
3040 3050 if (P->state == PS_DEAD) {
3041 3051 core_info_t *core = P->data;
3042 3052 lwp_info_t *lwp;
3043 3053
3044 3054 for (lwp = list_tail(&core->core_lwp_head); lwp != NULL;
3045 3055 lwp = list_prev(&core->core_lwp_head, lwp)) {
3046 3056 sp = (lwp->lwp_psinfo.pr_sname == 'Z')? NULL :
3047 3057 &lwp->lwp_status;
3048 3058 if ((rv = func(cd, sp, &lwp->lwp_psinfo)) != 0)
3049 3059 break;
3050 3060 }
3051 3061
3052 3062 return (rv);
3053 3063 }
3054 3064
3055 3065 /*
3056 3066 * For all other cases retrieve the array of lwpstatus_t's and
3057 3067 * lwpsinfo_t's.
3058 3068 */
3059 3069 if ((Lhp = Plstatus(P)) == NULL)
3060 3070 return (-1);
3061 3071 if ((Lphp = Plpsinfo(P)) == NULL) {
3062 3072 free(Lhp);
3063 3073 return (-1);
3064 3074 }
3065 3075
3066 3076 /*
3067 3077 * If we are looking at a running process, or one we do not control,
3068 3078 * the active and zombie lwps in the process may have changed since
3069 3079 * we read the process status structure. If so, just start over.
3070 3080 */
3071 3081 if (Lhp->pr_nent != P->status.pr_nlwp ||
3072 3082 Lphp->pr_nent != P->status.pr_nlwp + P->status.pr_nzomb)
3073 3083 goto retry;
3074 3084
3075 3085 /*
3076 3086 * To be perfectly safe, prescan the two arrays, checking consistency.
3077 3087 * We rely on /proc giving us lwpstatus_t's and lwpsinfo_t's in the
3078 3088 * same order (the lwp directory order) in their respective files.
3079 3089 * We also rely on there being (possibly) more lwpsinfo_t's than
3080 3090 * lwpstatus_t's (the extra lwpsinfo_t's are for zombie lwps).
3081 3091 */
3082 3092 Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
3083 3093 Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1);
3084 3094 nstat = Lhp->pr_nent;
3085 3095 for (ninfo = Lphp->pr_nent; ninfo != 0; ninfo--) {
3086 3096 if (Lpsp->pr_sname != 'Z') {
3087 3097 /*
3088 3098 * Not a zombie lwp; check for matching lwpids.
3089 3099 */
3090 3100 if (nstat == 0 || Lsp->pr_lwpid != Lpsp->pr_lwpid)
3091 3101 goto retry;
3092 3102 Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize);
3093 3103 nstat--;
3094 3104 }
3095 3105 Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize);
3096 3106 }
3097 3107 if (nstat != 0)
3098 3108 goto retry;
3099 3109
3100 3110 /*
3101 3111 * Rescan, this time for real.
3102 3112 */
3103 3113 Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
3104 3114 Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1);
3105 3115 for (ninfo = Lphp->pr_nent; ninfo != 0; ninfo--) {
3106 3116 if (Lpsp->pr_sname != 'Z') {
3107 3117 sp = Lsp;
3108 3118 Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize);
3109 3119 } else {
3110 3120 sp = NULL;
3111 3121 }
3112 3122 if ((rv = func(cd, sp, Lpsp)) != 0)
3113 3123 break;
3114 3124 Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize);
3115 3125 }
3116 3126
3117 3127 free(Lhp);
3118 3128 free(Lphp);
3119 3129 return (rv);
3120 3130 }
3121 3131
3122 3132 core_content_t
3123 3133 Pcontent(struct ps_prochandle *P)
3124 3134 {
3125 3135 core_info_t *core = P->data;
3126 3136
3127 3137 if (P->state == PS_DEAD)
3128 3138 return (core->core_content);
3129 3139 if (P->state == PS_IDLE)
3130 3140 return (CC_CONTENT_TEXT | CC_CONTENT_DATA | CC_CONTENT_CTF);
3131 3141
3132 3142 return (CC_CONTENT_ALL);
3133 3143 }
3134 3144
3135 3145 /*
3136 3146 * =================================================================
3137 3147 * The remainder of the functions in this file are for the
3138 3148 * control of individual LWPs in the controlled process.
3139 3149 * =================================================================
3140 3150 */
3141 3151
3142 3152 /*
3143 3153 * Find an entry in the process hash table for the specified lwpid.
3144 3154 * The entry will either point to an existing struct ps_lwphandle
3145 3155 * or it will point to an empty slot for a new struct ps_lwphandle.
3146 3156 */
3147 3157 static struct ps_lwphandle **
3148 3158 Lfind_slot(struct ps_prochandle *P, lwpid_t lwpid)
3149 3159 {
3150 3160 struct ps_lwphandle **Lp;
3151 3161 struct ps_lwphandle *L;
3152 3162
3153 3163 for (Lp = &P->hashtab[lwpid % (HASHSIZE - 1)];
3154 3164 (L = *Lp) != NULL; Lp = &L->lwp_hash)
3155 3165 if (L->lwp_id == lwpid)
3156 3166 break;
3157 3167 return (Lp);
3158 3168 }
3159 3169
3160 3170 /*
3161 3171 * A wrapper around Lfind_slot() that is suitable for the rest of the internal
3162 3172 * consumers who don't care about a slot, merely existence.
3163 3173 */
3164 3174 struct ps_lwphandle *
3165 3175 Lfind(struct ps_prochandle *P, lwpid_t lwpid)
3166 3176 {
3167 3177 if (P->hashtab == NULL) {
3168 3178 return (NULL);
3169 3179 }
3170 3180
3171 3181 return (*Lfind_slot(P, lwpid));
3172 3182 }
3173 3183
3174 3184 /*
3175 3185 * Grab an LWP contained within the controlled process.
3176 3186 * Return an opaque pointer to its LWP control structure.
3177 3187 * perr: pointer to error return code.
3178 3188 */
3179 3189 struct ps_lwphandle *
3180 3190 Lgrab(struct ps_prochandle *P, lwpid_t lwpid, int *perr)
3181 3191 {
3182 3192 struct ps_lwphandle **Lp;
3183 3193 struct ps_lwphandle *L;
3184 3194 int fd;
3185 3195 char procname[PATH_MAX];
3186 3196 char *fname;
3187 3197 int rc = 0;
3188 3198
3189 3199 (void) mutex_lock(&P->proc_lock);
3190 3200
3191 3201 if (P->state == PS_UNDEAD || P->state == PS_IDLE)
3192 3202 rc = G_NOPROC;
3193 3203 else if (P->hashtab == NULL &&
3194 3204 (P->hashtab = calloc(HASHSIZE, sizeof (struct ps_lwphandle *)))
3195 3205 == NULL)
3196 3206 rc = G_STRANGE;
3197 3207 else if (*(Lp = Lfind_slot(P, lwpid)) != NULL)
3198 3208 rc = G_BUSY;
3199 3209 else if ((L = malloc(sizeof (struct ps_lwphandle))) == NULL)
3200 3210 rc = G_STRANGE;
3201 3211 if (rc) {
3202 3212 *perr = rc;
3203 3213 (void) mutex_unlock(&P->proc_lock);
3204 3214 return (NULL);
3205 3215 }
3206 3216
3207 3217 (void) memset(L, 0, sizeof (*L));
3208 3218 L->lwp_ctlfd = -1;
3209 3219 L->lwp_statfd = -1;
3210 3220 L->lwp_proc = P;
3211 3221 L->lwp_id = lwpid;
3212 3222 *Lp = L; /* insert into the hash table */
3213 3223
3214 3224 if (P->state == PS_DEAD) { /* core file */
3215 3225 if (getlwpstatus(P, lwpid, &L->lwp_status) == -1) {
3216 3226 rc = G_NOPROC;
3217 3227 goto err;
3218 3228 }
3219 3229 L->lwp_state = PS_DEAD;
3220 3230 *perr = 0;
3221 3231 (void) mutex_unlock(&P->proc_lock);
3222 3232 return (L);
3223 3233 }
3224 3234
3225 3235 /*
3226 3236 * Open the /proc/<pid>/lwp/<lwpid> files
3227 3237 */
3228 3238 (void) snprintf(procname, sizeof (procname), "%s/%d/lwp/%d/",
3229 3239 procfs_path, (int)P->pid, (int)lwpid);
3230 3240 fname = procname + strlen(procname);
3231 3241 (void) set_minfd();
3232 3242
3233 3243 (void) strcpy(fname, "lwpstatus");
3234 3244 if ((fd = open(procname, O_RDONLY)) < 0 ||
3235 3245 (fd = dupfd(fd, 0)) < 0) {
3236 3246 switch (errno) {
3237 3247 case ENOENT:
3238 3248 rc = G_NOPROC;
3239 3249 break;
3240 3250 default:
3241 3251 dprintf("Lgrab: failed to open %s: %s\n",
3242 3252 procname, strerror(errno));
3243 3253 rc = G_STRANGE;
3244 3254 break;
3245 3255 }
3246 3256 goto err;
3247 3257 }
3248 3258 L->lwp_statfd = fd;
3249 3259
3250 3260 if (pread(fd, &L->lwp_status, sizeof (L->lwp_status), (off_t)0) < 0) {
3251 3261 switch (errno) {
3252 3262 case ENOENT:
3253 3263 rc = G_NOPROC;
3254 3264 break;
3255 3265 default:
3256 3266 dprintf("Lgrab: failed to read %s: %s\n",
3257 3267 procname, strerror(errno));
3258 3268 rc = G_STRANGE;
3259 3269 break;
3260 3270 }
3261 3271 goto err;
3262 3272 }
3263 3273
3264 3274 (void) strcpy(fname, "lwpctl");
3265 3275 if ((fd = open(procname, O_WRONLY)) < 0 ||
3266 3276 (fd = dupfd(fd, 0)) < 0) {
3267 3277 switch (errno) {
3268 3278 case ENOENT:
3269 3279 rc = G_NOPROC;
3270 3280 break;
3271 3281 default:
3272 3282 dprintf("Lgrab: failed to open %s: %s\n",
3273 3283 procname, strerror(errno));
3274 3284 rc = G_STRANGE;
3275 3285 break;
3276 3286 }
3277 3287 goto err;
3278 3288 }
3279 3289 L->lwp_ctlfd = fd;
3280 3290
3281 3291 L->lwp_state =
3282 3292 ((L->lwp_status.pr_flags & (PR_STOPPED|PR_ISTOP))
3283 3293 == (PR_STOPPED|PR_ISTOP))?
3284 3294 PS_STOP : PS_RUN;
3285 3295
3286 3296 *perr = 0;
3287 3297 (void) mutex_unlock(&P->proc_lock);
3288 3298 return (L);
3289 3299
3290 3300 err:
3291 3301 Lfree_internal(P, L);
3292 3302 *perr = rc;
3293 3303 (void) mutex_unlock(&P->proc_lock);
3294 3304 return (NULL);
3295 3305 }
3296 3306
3297 3307 /*
3298 3308 * Return a printable string corresponding to an Lgrab() error return.
3299 3309 */
3300 3310 const char *
3301 3311 Lgrab_error(int error)
3302 3312 {
3303 3313 const char *str;
3304 3314
3305 3315 switch (error) {
3306 3316 case G_NOPROC:
3307 3317 str = "no such LWP";
3308 3318 break;
3309 3319 case G_BUSY:
3310 3320 str = "LWP already grabbed";
3311 3321 break;
3312 3322 case G_STRANGE:
3313 3323 str = "unanticipated system error";
3314 3324 break;
3315 3325 default:
3316 3326 str = "unknown error";
3317 3327 break;
3318 3328 }
3319 3329
3320 3330 return (str);
3321 3331 }
3322 3332
3323 3333 /*
3324 3334 * Free an LWP control structure.
3325 3335 */
3326 3336 void
3327 3337 Lfree(struct ps_lwphandle *L)
3328 3338 {
3329 3339 struct ps_prochandle *P = L->lwp_proc;
3330 3340
3331 3341 (void) mutex_lock(&P->proc_lock);
3332 3342 Lfree_internal(P, L);
3333 3343 (void) mutex_unlock(&P->proc_lock);
3334 3344 }
3335 3345
3336 3346 static void
3337 3347 Lfree_internal(struct ps_prochandle *P, struct ps_lwphandle *L)
3338 3348 {
3339 3349 *Lfind_slot(P, L->lwp_id) = L->lwp_hash; /* delete from hash table */
3340 3350 if (L->lwp_ctlfd >= 0)
3341 3351 (void) close(L->lwp_ctlfd);
3342 3352 if (L->lwp_statfd >= 0)
3343 3353 (void) close(L->lwp_statfd);
3344 3354
3345 3355 /* clear out the structure as a precaution against reuse */
3346 3356 (void) memset(L, 0, sizeof (*L));
3347 3357 L->lwp_ctlfd = -1;
3348 3358 L->lwp_statfd = -1;
3349 3359
3350 3360 free(L);
3351 3361 }
3352 3362
3353 3363 /*
3354 3364 * Return the state of the process, one of the PS_* values.
3355 3365 */
3356 3366 int
3357 3367 Lstate(struct ps_lwphandle *L)
3358 3368 {
3359 3369 return (L->lwp_state);
3360 3370 }
3361 3371
3362 3372 /*
3363 3373 * Return the open control file descriptor for the LWP.
3364 3374 * Clients must not close this file descriptor, nor use it
3365 3375 * after the LWP is freed.
3366 3376 */
3367 3377 int
3368 3378 Lctlfd(struct ps_lwphandle *L)
3369 3379 {
3370 3380 return (L->lwp_ctlfd);
3371 3381 }
3372 3382
3373 3383 /*
3374 3384 * Return a pointer to the LWP lwpsinfo structure.
3375 3385 * Clients should not hold on to this pointer indefinitely.
3376 3386 * It will become invalid on Lfree().
3377 3387 */
3378 3388 const lwpsinfo_t *
3379 3389 Lpsinfo(struct ps_lwphandle *L)
3380 3390 {
3381 3391 if (Plwp_getpsinfo(L->lwp_proc, L->lwp_id, &L->lwp_psinfo) == -1)
3382 3392 return (NULL);
3383 3393
3384 3394 return (&L->lwp_psinfo);
3385 3395 }
3386 3396
3387 3397 /*
3388 3398 * Return a pointer to the LWP status structure.
3389 3399 * Clients should not hold on to this pointer indefinitely.
3390 3400 * It will become invalid on Lfree().
3391 3401 */
3392 3402 const lwpstatus_t *
3393 3403 Lstatus(struct ps_lwphandle *L)
3394 3404 {
3395 3405 return (&L->lwp_status);
3396 3406 }
3397 3407
3398 3408 /*
3399 3409 * Given an LWP handle, return the process handle.
3400 3410 */
3401 3411 struct ps_prochandle *
3402 3412 Lprochandle(struct ps_lwphandle *L)
3403 3413 {
3404 3414 return (L->lwp_proc);
3405 3415 }
3406 3416
3407 3417 /*
3408 3418 * Ensure that all cached state is written to the LWP.
3409 3419 * The cached state is the LWP's signal mask and registers.
3410 3420 */
3411 3421 void
3412 3422 Lsync(struct ps_lwphandle *L)
3413 3423 {
3414 3424 int ctlfd = L->lwp_ctlfd;
3415 3425 long cmd[2];
3416 3426 iovec_t iov[4];
3417 3427 int n = 0;
3418 3428
3419 3429 if (L->lwp_flags & SETHOLD) {
3420 3430 cmd[0] = PCSHOLD;
3421 3431 iov[n].iov_base = (caddr_t)&cmd[0];
3422 3432 iov[n++].iov_len = sizeof (long);
3423 3433 iov[n].iov_base = (caddr_t)&L->lwp_status.pr_lwphold;
3424 3434 iov[n++].iov_len = sizeof (L->lwp_status.pr_lwphold);
3425 3435 }
3426 3436 if (L->lwp_flags & SETREGS) {
3427 3437 cmd[1] = PCSREG;
3428 3438 iov[n].iov_base = (caddr_t)&cmd[1];
3429 3439 iov[n++].iov_len = sizeof (long);
3430 3440 iov[n].iov_base = (caddr_t)&L->lwp_status.pr_reg[0];
3431 3441 iov[n++].iov_len = sizeof (L->lwp_status.pr_reg);
3432 3442 }
3433 3443
3434 3444 if (n == 0 || writev(ctlfd, iov, n) < 0)
3435 3445 return; /* nothing to do or write failed */
3436 3446
3437 3447 L->lwp_flags &= ~(SETHOLD|SETREGS);
3438 3448 }
3439 3449
3440 3450 /*
3441 3451 * Wait for the specified LWP to stop or terminate.
3442 3452 * Or, just get the current status (PCNULL).
3443 3453 * Or, direct it to stop and get the current status (PCDSTOP).
3444 3454 */
3445 3455 int
3446 3456 Lstopstatus(struct ps_lwphandle *L,
3447 3457 long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
3448 3458 uint_t msec) /* if non-zero, timeout in milliseconds */
3449 3459 {
3450 3460 int ctlfd = L->lwp_ctlfd;
3451 3461 long ctl[3];
3452 3462 ssize_t rc;
3453 3463 int err;
3454 3464
3455 3465 switch (L->lwp_state) {
3456 3466 case PS_RUN:
3457 3467 break;
3458 3468 case PS_STOP:
3459 3469 if (request != PCNULL && request != PCDSTOP)
3460 3470 return (0);
3461 3471 break;
3462 3472 case PS_LOST:
3463 3473 if (request != PCNULL) {
3464 3474 errno = EAGAIN;
3465 3475 return (-1);
3466 3476 }
3467 3477 break;
3468 3478 case PS_UNDEAD:
3469 3479 case PS_DEAD:
3470 3480 if (request != PCNULL) {
3471 3481 errno = ENOENT;
3472 3482 return (-1);
3473 3483 }
3474 3484 break;
3475 3485 default: /* corrupted state */
3476 3486 dprintf("Lstopstatus: corrupted state: %d\n", L->lwp_state);
3477 3487 errno = EINVAL;
3478 3488 return (-1);
3479 3489 }
3480 3490
3481 3491 ctl[0] = PCDSTOP;
3482 3492 ctl[1] = PCTWSTOP;
3483 3493 ctl[2] = (long)msec;
3484 3494 rc = 0;
3485 3495 switch (request) {
3486 3496 case PCSTOP:
3487 3497 rc = write(ctlfd, &ctl[0], 3*sizeof (long));
3488 3498 break;
3489 3499 case PCWSTOP:
3490 3500 rc = write(ctlfd, &ctl[1], 2*sizeof (long));
3491 3501 break;
3492 3502 case PCDSTOP:
3493 3503 rc = write(ctlfd, &ctl[0], 1*sizeof (long));
3494 3504 break;
3495 3505 case PCNULL:
3496 3506 if (L->lwp_state == PS_DEAD)
3497 3507 return (0); /* Nothing else to do for cores */
3498 3508 break;
3499 3509 default: /* programming error */
3500 3510 errno = EINVAL;
3501 3511 return (-1);
3502 3512 }
3503 3513 err = (rc < 0)? errno : 0;
3504 3514 Lsync(L);
3505 3515
3506 3516 if (pread(L->lwp_statfd, &L->lwp_status,
3507 3517 sizeof (L->lwp_status), (off_t)0) < 0)
3508 3518 err = errno;
3509 3519
3510 3520 if (err) {
3511 3521 switch (err) {
3512 3522 case EINTR: /* user typed ctl-C */
3513 3523 case ERESTART:
3514 3524 dprintf("Lstopstatus: EINTR\n");
3515 3525 break;
3516 3526 case EAGAIN: /* we lost control of the the process */
3517 3527 dprintf("Lstopstatus: EAGAIN\n");
3518 3528 L->lwp_state = PS_LOST;
3519 3529 errno = err;
3520 3530 return (-1);
3521 3531 default:
3522 3532 if (_libproc_debug) {
3523 3533 const char *errstr;
3524 3534
3525 3535 switch (request) {
3526 3536 case PCNULL:
3527 3537 errstr = "Lstopstatus PCNULL"; break;
3528 3538 case PCSTOP:
3529 3539 errstr = "Lstopstatus PCSTOP"; break;
3530 3540 case PCDSTOP:
3531 3541 errstr = "Lstopstatus PCDSTOP"; break;
3532 3542 case PCWSTOP:
3533 3543 errstr = "Lstopstatus PCWSTOP"; break;
3534 3544 default:
3535 3545 errstr = "Lstopstatus PC???"; break;
3536 3546 }
3537 3547 dprintf("%s: %s\n", errstr, strerror(err));
3538 3548 }
3539 3549 L->lwp_state = PS_UNDEAD;
3540 3550 errno = err;
3541 3551 return (-1);
3542 3552 }
3543 3553 }
3544 3554
3545 3555 if ((L->lwp_status.pr_flags & (PR_STOPPED|PR_ISTOP))
3546 3556 != (PR_STOPPED|PR_ISTOP)) {
3547 3557 L->lwp_state = PS_RUN;
3548 3558 if (request == PCNULL || request == PCDSTOP || msec != 0)
3549 3559 return (0);
3550 3560 dprintf("Lstopstatus: LWP is not stopped\n");
3551 3561 errno = EPROTO;
3552 3562 return (-1);
3553 3563 }
3554 3564
3555 3565 L->lwp_state = PS_STOP;
3556 3566
3557 3567 if (_libproc_debug) /* debugging */
|
↓ open down ↓ |
1568 lines elided |
↑ open up ↑ |
3558 3568 prldump("Lstopstatus", &L->lwp_status);
3559 3569
3560 3570 switch (L->lwp_status.pr_why) {
3561 3571 case PR_SYSENTRY:
3562 3572 case PR_SYSEXIT:
3563 3573 case PR_REQUESTED:
3564 3574 case PR_SIGNALLED:
3565 3575 case PR_FAULTED:
3566 3576 case PR_JOBCONTROL:
3567 3577 case PR_SUSPENDED:
3578 + case PR_BRAND:
3568 3579 break;
3569 3580 default:
3570 3581 errno = EPROTO;
3571 3582 return (-1);
3572 3583 }
3573 3584
3574 3585 return (0);
3575 3586 }
3576 3587
3577 3588 /*
3578 3589 * Wait for the LWP to stop for any reason.
3579 3590 */
3580 3591 int
3581 3592 Lwait(struct ps_lwphandle *L, uint_t msec)
3582 3593 {
3583 3594 return (Lstopstatus(L, PCWSTOP, msec));
3584 3595 }
3585 3596
3586 3597 /*
3587 3598 * Direct the LWP to stop; wait for it to stop.
3588 3599 */
3589 3600 int
3590 3601 Lstop(struct ps_lwphandle *L, uint_t msec)
3591 3602 {
3592 3603 return (Lstopstatus(L, PCSTOP, msec));
3593 3604 }
3594 3605
3595 3606 /*
3596 3607 * Direct the LWP to stop; don't wait.
3597 3608 */
3598 3609 int
3599 3610 Ldstop(struct ps_lwphandle *L)
3600 3611 {
3601 3612 return (Lstopstatus(L, PCDSTOP, 0));
3602 3613 }
3603 3614
3604 3615 /*
3605 3616 * Get the value of one register from stopped LWP.
3606 3617 */
3607 3618 int
3608 3619 Lgetareg(struct ps_lwphandle *L, int regno, prgreg_t *preg)
3609 3620 {
3610 3621 if (regno < 0 || regno >= NPRGREG) {
3611 3622 errno = EINVAL;
3612 3623 return (-1);
3613 3624 }
3614 3625
3615 3626 if (L->lwp_state != PS_STOP) {
3616 3627 errno = EBUSY;
3617 3628 return (-1);
3618 3629 }
3619 3630
3620 3631 *preg = L->lwp_status.pr_reg[regno];
3621 3632 return (0);
3622 3633 }
3623 3634
3624 3635 /*
3625 3636 * Put value of one register into stopped LWP.
3626 3637 */
3627 3638 int
3628 3639 Lputareg(struct ps_lwphandle *L, int regno, prgreg_t reg)
3629 3640 {
3630 3641 if (regno < 0 || regno >= NPRGREG) {
3631 3642 errno = EINVAL;
3632 3643 return (-1);
3633 3644 }
3634 3645
3635 3646 if (L->lwp_state != PS_STOP) {
3636 3647 errno = EBUSY;
3637 3648 return (-1);
3638 3649 }
3639 3650
3640 3651 L->lwp_status.pr_reg[regno] = reg;
3641 3652 L->lwp_flags |= SETREGS; /* set registers before continuing */
3642 3653 return (0);
3643 3654 }
3644 3655
3645 3656 int
3646 3657 Lsetrun(struct ps_lwphandle *L,
3647 3658 int sig, /* signal to pass to LWP */
3648 3659 int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
3649 3660 {
3650 3661 int ctlfd = L->lwp_ctlfd;
3651 3662 int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP);
3652 3663
3653 3664 long ctl[1 + /* PCCFAULT */
3654 3665 1 + sizeof (siginfo_t)/sizeof (long) + /* PCSSIG/PCCSIG */
3655 3666 2 ]; /* PCRUN */
3656 3667
3657 3668 long *ctlp = ctl;
3658 3669 size_t size;
3659 3670
3660 3671 if (L->lwp_state != PS_STOP &&
3661 3672 (L->lwp_status.pr_flags & sbits) == 0) {
3662 3673 errno = EBUSY;
3663 3674 return (-1);
3664 3675 }
3665 3676
3666 3677 Lsync(L); /* flush registers */
3667 3678
3668 3679 if (flags & PRCFAULT) { /* clear current fault */
3669 3680 *ctlp++ = PCCFAULT;
3670 3681 flags &= ~PRCFAULT;
3671 3682 }
3672 3683
3673 3684 if (flags & PRCSIG) { /* clear current signal */
3674 3685 *ctlp++ = PCCSIG;
3675 3686 flags &= ~PRCSIG;
3676 3687 } else if (sig && sig != L->lwp_status.pr_cursig) {
3677 3688 /* make current signal */
3678 3689 siginfo_t *infop;
3679 3690
3680 3691 *ctlp++ = PCSSIG;
3681 3692 infop = (siginfo_t *)ctlp;
3682 3693 (void) memset(infop, 0, sizeof (*infop));
3683 3694 infop->si_signo = sig;
3684 3695 ctlp += sizeof (siginfo_t) / sizeof (long);
3685 3696 }
3686 3697
3687 3698 *ctlp++ = PCRUN;
3688 3699 *ctlp++ = flags;
3689 3700 size = (char *)ctlp - (char *)ctl;
3690 3701
3691 3702 L->lwp_proc->info_valid = 0; /* will need to update map and file info */
3692 3703 L->lwp_proc->state = PS_RUN;
3693 3704 L->lwp_state = PS_RUN;
3694 3705
3695 3706 if (write(ctlfd, ctl, size) != size) {
3696 3707 /* Pretend that a job-stopped LWP is running */
3697 3708 if (errno != EBUSY || L->lwp_status.pr_why != PR_JOBCONTROL)
3698 3709 return (Lstopstatus(L, PCNULL, 0));
3699 3710 }
3700 3711
3701 3712 return (0);
3702 3713 }
3703 3714
3704 3715 int
3705 3716 Lclearsig(struct ps_lwphandle *L)
3706 3717 {
3707 3718 int ctlfd = L->lwp_ctlfd;
3708 3719 long ctl = PCCSIG;
3709 3720
3710 3721 if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
3711 3722 return (-1);
3712 3723 L->lwp_status.pr_cursig = 0;
3713 3724 return (0);
3714 3725 }
3715 3726
3716 3727 int
3717 3728 Lclearfault(struct ps_lwphandle *L)
3718 3729 {
3719 3730 int ctlfd = L->lwp_ctlfd;
3720 3731 long ctl = PCCFAULT;
3721 3732
3722 3733 if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
3723 3734 return (-1);
3724 3735 return (0);
3725 3736 }
3726 3737
3727 3738 /*
3728 3739 * Step over a breakpoint, i.e., execute the instruction that
3729 3740 * really belongs at the breakpoint location (the current %pc)
3730 3741 * and leave the LWP stopped at the next instruction.
3731 3742 */
3732 3743 int
3733 3744 Lxecbkpt(struct ps_lwphandle *L, ulong_t saved)
3734 3745 {
3735 3746 struct ps_prochandle *P = L->lwp_proc;
3736 3747 int rv, error;
3737 3748
3738 3749 if (L->lwp_state != PS_STOP) {
3739 3750 errno = EBUSY;
3740 3751 return (-1);
3741 3752 }
3742 3753
3743 3754 Lsync(L);
3744 3755 error = execute_bkpt(L->lwp_ctlfd,
3745 3756 &P->status.pr_flttrace, &L->lwp_status.pr_lwphold,
3746 3757 L->lwp_status.pr_reg[R_PC], saved);
3747 3758 rv = Lstopstatus(L, PCNULL, 0);
3748 3759
3749 3760 if (error != 0) {
3750 3761 if (L->lwp_status.pr_why == PR_JOBCONTROL &&
3751 3762 error == EBUSY) { /* jobcontrol stop -- back off */
3752 3763 L->lwp_state = PS_RUN;
3753 3764 return (0);
3754 3765 }
3755 3766 if (error == ENOENT)
3756 3767 return (0);
3757 3768 errno = error;
3758 3769 return (-1);
3759 3770 }
3760 3771
3761 3772 return (rv);
3762 3773 }
3763 3774
3764 3775 /*
3765 3776 * Step over a watchpoint, i.e., execute the instruction that was stopped by
3766 3777 * the watchpoint, and then leave the LWP stopped at the next instruction.
3767 3778 */
3768 3779 int
3769 3780 Lxecwapt(struct ps_lwphandle *L, const prwatch_t *wp)
3770 3781 {
3771 3782 struct ps_prochandle *P = L->lwp_proc;
3772 3783 int rv, error;
3773 3784
3774 3785 if (L->lwp_state != PS_STOP) {
3775 3786 errno = EBUSY;
3776 3787 return (-1);
3777 3788 }
3778 3789
3779 3790 Lsync(L);
3780 3791 error = execute_wapt(L->lwp_ctlfd,
3781 3792 &P->status.pr_flttrace, &L->lwp_status.pr_lwphold, wp);
3782 3793 rv = Lstopstatus(L, PCNULL, 0);
3783 3794
3784 3795 if (error != 0) {
3785 3796 if (L->lwp_status.pr_why == PR_JOBCONTROL &&
3786 3797 error == EBUSY) { /* jobcontrol stop -- back off */
3787 3798 L->lwp_state = PS_RUN;
3788 3799 return (0);
3789 3800 }
3790 3801 if (error == ENOENT)
3791 3802 return (0);
3792 3803 errno = error;
3793 3804 return (-1);
3794 3805 }
3795 3806
3796 3807 return (rv);
3797 3808 }
3798 3809
3799 3810 int
3800 3811 Lstack(struct ps_lwphandle *L, stack_t *stkp)
3801 3812 {
3802 3813 struct ps_prochandle *P = L->lwp_proc;
3803 3814 uintptr_t addr = L->lwp_status.pr_ustack;
3804 3815
3805 3816 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
3806 3817 if (Pread(P, stkp, sizeof (*stkp), addr) != sizeof (*stkp))
3807 3818 return (-1);
3808 3819 #ifdef _LP64
3809 3820 } else {
3810 3821 stack32_t stk32;
3811 3822
3812 3823 if (Pread(P, &stk32, sizeof (stk32), addr) != sizeof (stk32))
3813 3824 return (-1);
3814 3825
3815 3826 stack_32_to_n(&stk32, stkp);
3816 3827 #endif
3817 3828 }
3818 3829
3819 3830 return (0);
3820 3831 }
3821 3832
3822 3833 int
3823 3834 Lmain_stack(struct ps_lwphandle *L, stack_t *stkp)
3824 3835 {
3825 3836 struct ps_prochandle *P = L->lwp_proc;
3826 3837
3827 3838 if (Lstack(L, stkp) != 0)
3828 3839 return (-1);
3829 3840
3830 3841 /*
3831 3842 * If the SS_ONSTACK flag is set then this LWP is operating on the
3832 3843 * alternate signal stack. We can recover the original stack from
3833 3844 * pr_oldcontext.
3834 3845 */
3835 3846 if (!(stkp->ss_flags & SS_ONSTACK))
3836 3847 return (0);
3837 3848
3838 3849 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
3839 3850 ucontext_t *ctxp = (void *)L->lwp_status.pr_oldcontext;
3840 3851
3841 3852 if (Pread(P, stkp, sizeof (*stkp),
3842 3853 (uintptr_t)&ctxp->uc_stack) != sizeof (*stkp))
3843 3854 return (-1);
3844 3855 #ifdef _LP64
3845 3856 } else {
3846 3857 ucontext32_t *ctxp = (void *)L->lwp_status.pr_oldcontext;
3847 3858 stack32_t stk32;
3848 3859
3849 3860 if (Pread(P, &stk32, sizeof (stk32),
3850 3861 (uintptr_t)&ctxp->uc_stack) != sizeof (stk32))
3851 3862 return (-1);
3852 3863
3853 3864 stack_32_to_n(&stk32, stkp);
3854 3865 #endif
3855 3866 }
3856 3867
3857 3868 return (0);
3858 3869 }
3859 3870
3860 3871 int
3861 3872 Lalt_stack(struct ps_lwphandle *L, stack_t *stkp)
3862 3873 {
3863 3874 if (L->lwp_status.pr_altstack.ss_flags & SS_DISABLE) {
3864 3875 errno = ENODATA;
3865 3876 return (-1);
3866 3877 }
3867 3878
3868 3879 *stkp = L->lwp_status.pr_altstack;
3869 3880
3870 3881 return (0);
3871 3882 }
3872 3883
3873 3884 /*
3874 3885 * Add a mapping to the given proc handle. Resizes the array as appropriate and
3875 3886 * manages reference counts on the given file_info_t.
3876 3887 *
3877 3888 * The 'map_relocate' member is used to tell Psort_mappings() that the
3878 3889 * associated file_map pointer needs to be relocated after the mappings have
3879 3890 * been sorted. It is only set for the first mapping, and has no meaning
3880 3891 * outside these two functions.
3881 3892 */
3882 3893 int
3883 3894 Padd_mapping(struct ps_prochandle *P, off64_t off, file_info_t *fp,
3884 3895 prmap_t *pmap)
3885 3896 {
3886 3897 map_info_t *mp;
3887 3898
3888 3899 if (P->map_count == P->map_alloc) {
3889 3900 size_t next = P->map_alloc ? P->map_alloc * 2 : 16;
3890 3901
3891 3902 if ((P->mappings = realloc(P->mappings,
3892 3903 next * sizeof (map_info_t))) == NULL)
3893 3904 return (-1);
3894 3905
3895 3906 P->map_alloc = next;
3896 3907 }
3897 3908
3898 3909 mp = &P->mappings[P->map_count++];
3899 3910
3900 3911 mp->map_offset = off;
3901 3912 mp->map_pmap = *pmap;
3902 3913 mp->map_relocate = 0;
3903 3914 if ((mp->map_file = fp) != NULL) {
3904 3915 if (fp->file_map == NULL) {
3905 3916 fp->file_map = mp;
3906 3917 mp->map_relocate = 1;
3907 3918 }
3908 3919 fp->file_ref++;
3909 3920 }
3910 3921
3911 3922 return (0);
3912 3923 }
3913 3924
3914 3925 static int
3915 3926 map_sort(const void *a, const void *b)
3916 3927 {
3917 3928 const map_info_t *ap = a, *bp = b;
3918 3929
3919 3930 if (ap->map_pmap.pr_vaddr < bp->map_pmap.pr_vaddr)
3920 3931 return (-1);
3921 3932 else if (ap->map_pmap.pr_vaddr > bp->map_pmap.pr_vaddr)
3922 3933 return (1);
3923 3934 else
3924 3935 return (0);
3925 3936 }
3926 3937
3927 3938 /*
3928 3939 * Sort the current set of mappings. Should be called during target
3929 3940 * initialization after all calls to Padd_mapping() have been made.
3930 3941 */
3931 3942 void
3932 3943 Psort_mappings(struct ps_prochandle *P)
3933 3944 {
3934 3945 int i;
3935 3946 map_info_t *mp;
3936 3947
3937 3948 qsort(P->mappings, P->map_count, sizeof (map_info_t), map_sort);
3938 3949
3939 3950 /*
3940 3951 * Update all the file_map pointers to refer to the new locations.
3941 3952 */
3942 3953 for (i = 0; i < P->map_count; i++) {
3943 3954 mp = &P->mappings[i];
3944 3955 if (mp->map_relocate)
3945 3956 mp->map_file->file_map = mp;
3946 3957 mp->map_relocate = 0;
3947 3958 }
3948 3959 }
3949 3960
3950 3961 struct ps_prochandle *
3951 3962 Pgrab_ops(pid_t pid, void *data, const ps_ops_t *ops, int flags)
3952 3963 {
3953 3964 struct ps_prochandle *P;
3954 3965
3955 3966 if ((P = calloc(1, sizeof (*P))) == NULL) {
3956 3967 return (NULL);
3957 3968 }
3958 3969
3959 3970 Pinit_ops(&P->ops, ops);
3960 3971 (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
3961 3972 P->pid = pid;
3962 3973 P->state = PS_STOP;
3963 3974 P->asfd = -1;
3964 3975 P->ctlfd = -1;
3965 3976 P->statfd = -1;
3966 3977 P->agentctlfd = -1;
3967 3978 P->agentstatfd = -1;
3968 3979 Pinitsym(P);
3969 3980 Pinitfd(P);
3970 3981 P->data = data;
3971 3982 Pread_status(P);
3972 3983
3973 3984 if (flags & PGRAB_INCORE) {
3974 3985 P->flags |= INCORE;
3975 3986 }
3976 3987
3977 3988 return (P);
3978 3989 }
|
↓ open down ↓ |
401 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX