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