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