static int stop(char *arg) { int gcode; int rc = 0; if ((P = proc_arg_xgrab(arg, NULL, PR_ARG_PIDS, PGRAB_RETAIN | PGRAB_NOSTOP | PGRAB_FORCE, &gcode, &lwps)) == NULL) { (void) fprintf(stderr, "%s: cannot control %s: %s\n", command, arg, Pgrab_error(gcode)); return (1); } else if (lwps != NULL) { /* * The user has provided an lwp specification. Let's consider * the lwp specification as a mask. We iterate over all lwps in * the process and stop every lwp, which matches the mask. If * there is no lwp matching the mask or an error occured during * the iteration, set the return code to 1 as indication of an * error. */ int lwpcount = 0; (void) Plwp_iter_all(P, (proc_lwp_all_f *)lwpstop, &lwpcount); if (lwpcount == 0) { (void) fprintf(stderr, "%s: cannot control %s:" " no matching LWPs found\n", command, arg); rc = 1; } else if (lwpcount == -1) rc = 1; } else { (void) Pdstop(P); /* Stop the process. */ } /* * Prelease could change the tracing flags, use Pfree and unset * run-on-last-close flag to prevent the process being set running * after detaching from it. */ (void) Punsetflags(P, PR_RLC); Pfree(P); return (rc); }
static int look(char *arg) { int gcode; int gcode2; pstatus_t pstatus; psinfo_t psinfo; int flags; sigset_t sigmask; fltset_t fltmask; sysset_t entryset; sysset_t exitset; uint32_t sigtrace, sigtrace1, sigtrace2, fltbits; uint32_t sigpend, sigpend1, sigpend2; uint32_t *bits; char buf[PRSIGBUFSZ]; look_arg_t lookarg; if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_ANY, PGRAB_RETAIN | PGRAB_FORCE | PGRAB_RDONLY | PGRAB_NOSTOP, &gcode, &lookarg.lwps)) == NULL) { if (gcode == G_NOPROC && proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gcode2) > 0 && psinfo.pr_nlwp == 0) { (void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid); return (0); } (void) fprintf(stderr, "%s: cannot examine %s: %s\n", command, arg, Pgrab_error(gcode)); return (1); } (void) memcpy(&pstatus, Pstatus(Pr), sizeof (pstatus_t)); (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t)); proc_unctrl_psinfo(&psinfo); if (psinfo.pr_nlwp == 0) { (void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid); Prelease(Pr, PRELEASE_RETAIN); return (0); } is64 = (pstatus.pr_dmodel == PR_MODEL_LP64); sigmask = pstatus.pr_sigtrace; fltmask = pstatus.pr_flttrace; entryset = pstatus.pr_sysentry; exitset = pstatus.pr_sysexit; if (Pstate(Pr) == PS_DEAD) { (void) printf("core '%s' of %d:\t%.70s\n", arg, (int)psinfo.pr_pid, psinfo.pr_psargs); } else { (void) printf("%d:\t%.70s\n", (int)psinfo.pr_pid, psinfo.pr_psargs); } (void) printf("\tdata model = %s", is64? "_LP64" : "_ILP32"); if ((flags = (pstatus.pr_flags & PROCFLAGS)) != 0) (void) printf(" flags = %s", prflags(flags)); (void) printf("\n"); fltbits = *((uint32_t *)&fltmask); if (fltbits) (void) printf("\tflttrace = 0x%.8x\n", fltbits); #if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32) /* assumption */ sigtrace = *((uint32_t *)&sigmask); sigtrace1 = *((uint32_t *)&sigmask + 1); sigtrace2 = *((uint32_t *)&sigmask + 2); #else #error "fix me: MAXSIG out of bounds" #endif if (sigtrace | sigtrace1 | sigtrace2) (void) printf("\tsigtrace = 0x%.8x 0x%.8x 0x%.8x\n\t %s\n", sigtrace, sigtrace1, sigtrace2, proc_sigset2str(&sigmask, "|", 1, buf, sizeof (buf))); bits = ((uint32_t *)&entryset); if (bits[0] | bits[1] | bits[2] | bits[3] | bits[4] | bits[5] | bits[6] | bits[7]) (void) printf( "\tentryset = " "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" "\t " "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); bits = ((uint32_t *)&exitset); if (bits[0] | bits[1] | bits[2] | bits[3] | bits[4] | bits[5] | bits[6] | bits[7]) (void) printf( "\texitset = " "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" "\t " "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); #if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32) /* assumption */ sigpend = *((uint32_t *)&pstatus.pr_sigpend); sigpend1 = *((uint32_t *)&pstatus.pr_sigpend + 1); sigpend2 = *((uint32_t *)&pstatus.pr_sigpend + 2); #else #error "fix me: MAXSIG out of bounds" #endif if (sigpend | sigpend1 | sigpend2) (void) printf("\tsigpend = 0x%.8x,0x%.8x,0x%.8x\n", sigpend, sigpend1, sigpend2); lookarg.pflags = pstatus.pr_flags; lookarg.count = 0; (void) Plwp_iter_all(Pr, (proc_lwp_all_f *)lwplook, &lookarg); if (lookarg.count == 0) (void) printf("No matching lwps found"); (void) printf("\n"); Prelease(Pr, PRELEASE_RETAIN); return (0); }
/* * Don't explicity stop the process; that's up to the consumer. */ int Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) { char plat[SYS_NMLN]; char zonename[ZONENAME_MAX]; int platlen = -1; pgcore_t pgc; off64_t poff, soff, doff, boff; struct utsname uts; uint_t nphdrs, nshdrs; if (ftruncate64(fd, 0) != 0) return (-1); if (content == CC_CONTENT_INVALID) { errno = EINVAL; return (-1); } /* * Cache the mappings and other useful data. */ (void) Prd_agent(P); (void) Ppsinfo(P); pgc.P = P; pgc.pgc_fd = fd; pgc.pgc_poff = &poff; pgc.pgc_soff = &soff; pgc.pgc_doff = &doff; pgc.pgc_content = content; pgc.pgc_chunksz = PAGESIZE; if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL) return (-1); shstrtab_init(&pgc.pgc_shstrtab); /* * There are two PT_NOTE program headers for ancillary data, and * one for each mapping. */ nphdrs = 2 + P->map_count; nshdrs = count_sections(&pgc); (void) Pplatform(P, plat, sizeof (plat)); platlen = strlen(plat) + 1; Preadauxvec(P); (void) Puname(P, &uts); if (Pzonename(P, zonename, sizeof (zonename)) == NULL) zonename[0] = '\0'; /* * The core file contents may required zero section headers, but if we * overflow the 16 bits allotted to the program header count in the ELF * header, we'll need that program header at index zero. */ if (nshdrs == 0 && nphdrs >= PN_XNUM) nshdrs = 1; /* * Set up the ELF header. */ if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Ehdr ehdr; bzero(&ehdr, sizeof (ehdr)); ehdr.e_ident[EI_MAG0] = ELFMAG0; ehdr.e_ident[EI_MAG1] = ELFMAG1; ehdr.e_ident[EI_MAG2] = ELFMAG2; ehdr.e_ident[EI_MAG3] = ELFMAG3; ehdr.e_type = ET_CORE; ehdr.e_ident[EI_CLASS] = ELFCLASS32; #if defined(__sparc) ehdr.e_machine = EM_SPARC; ehdr.e_ident[EI_DATA] = ELFDATA2MSB; #elif defined(__i386) || defined(__amd64) ehdr.e_machine = EM_386; ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #else #error "unknown machine type" #endif ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_version = EV_CURRENT; ehdr.e_ehsize = sizeof (ehdr); if (nphdrs >= PN_XNUM) ehdr.e_phnum = PN_XNUM; else ehdr.e_phnum = (unsigned short)nphdrs; ehdr.e_phentsize = sizeof (Elf32_Phdr); ehdr.e_phoff = ehdr.e_ehsize; if (nshdrs > 0) { if (nshdrs >= SHN_LORESERVE) ehdr.e_shnum = 0; else ehdr.e_shnum = (unsigned short)nshdrs; if (nshdrs - 1 >= SHN_LORESERVE) ehdr.e_shstrndx = SHN_XINDEX; else ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); ehdr.e_shentsize = sizeof (Elf32_Shdr); ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; } if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) goto err; poff = ehdr.e_phoff; soff = ehdr.e_shoff; doff = boff = ehdr.e_ehsize + ehdr.e_phentsize * nphdrs + ehdr.e_shentsize * nshdrs; #ifdef _LP64 } else { Elf64_Ehdr ehdr; bzero(&ehdr, sizeof (ehdr)); ehdr.e_ident[EI_MAG0] = ELFMAG0; ehdr.e_ident[EI_MAG1] = ELFMAG1; ehdr.e_ident[EI_MAG2] = ELFMAG2; ehdr.e_ident[EI_MAG3] = ELFMAG3; ehdr.e_type = ET_CORE; ehdr.e_ident[EI_CLASS] = ELFCLASS64; #if defined(__sparc) ehdr.e_machine = EM_SPARCV9; ehdr.e_ident[EI_DATA] = ELFDATA2MSB; #elif defined(__i386) || defined(__amd64) ehdr.e_machine = EM_AMD64; ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #else #error "unknown machine type" #endif ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_version = EV_CURRENT; ehdr.e_ehsize = sizeof (ehdr); if (nphdrs >= PN_XNUM) ehdr.e_phnum = PN_XNUM; else ehdr.e_phnum = (unsigned short)nphdrs; ehdr.e_phentsize = sizeof (Elf64_Phdr); ehdr.e_phoff = ehdr.e_ehsize; if (nshdrs > 0) { if (nshdrs >= SHN_LORESERVE) ehdr.e_shnum = 0; else ehdr.e_shnum = (unsigned short)nshdrs; if (nshdrs - 1 >= SHN_LORESERVE) ehdr.e_shstrndx = SHN_XINDEX; else ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); ehdr.e_shentsize = sizeof (Elf64_Shdr); ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; } if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) goto err; poff = ehdr.e_phoff; soff = ehdr.e_shoff; doff = boff = ehdr.e_ehsize + ehdr.e_phentsize * nphdrs + ehdr.e_shentsize * nshdrs; #endif /* _LP64 */ } /* * Write the zero indexed section if it exists. */ if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0, nshdrs >= SHN_LORESERVE ? nshdrs : 0, nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0, nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0) goto err; /* * Construct the old-style note header and section. */ if (P->status.pr_dmodel == PR_MODEL_NATIVE) { prpsinfo_t prpsinfo; mkprpsinfo(P, &prpsinfo); if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t), &doff) != 0) { goto err; } if (write_note(fd, NT_AUXV, P->auxv, P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { goto err; } #ifdef _LP64 } else { prpsinfo32_t pi32; auxv32_t *av32; size_t size = sizeof (auxv32_t) * P->nauxv; int i; mkprpsinfo32(P, &pi32); if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t), &doff) != 0) { goto err; } if ((av32 = malloc(size)) == NULL) goto err; for (i = 0; i < P->nauxv; i++) { auxv_n_to_32(&P->auxv[i], &av32[i]); } if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { free(av32); goto err; } free(av32); #endif /* _LP64 */ } if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0) goto err; if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0) goto err; if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = (Elf32_Off)boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #ifdef _LP64 } else { Elf64_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #endif /* _LP64 */ } /* * Construct the new-style note header and section. */ if (P->status.pr_dmodel == PR_MODEL_NATIVE) { if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t), &doff) != 0) { goto err; } if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t), &doff) != 0) { goto err; } if (write_note(fd, NT_AUXV, P->auxv, P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { goto err; } #ifdef _LP64 } else { psinfo32_t pi32; pstatus32_t ps32; auxv32_t *av32; size_t size = sizeof (auxv32_t) * P->nauxv; int i; psinfo_n_to_32(&P->psinfo, &pi32); if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t), &doff) != 0) { goto err; } pstatus_n_to_32(&P->status, &ps32); if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t), &doff) != 0) { goto err; } if ((av32 = malloc(size)) == NULL) goto err; for (i = 0; i < P->nauxv; i++) { auxv_n_to_32(&P->auxv[i], &av32[i]); } if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { free(av32); goto err; } free(av32); #endif /* _LP64 */ } if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 || write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 || write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0) goto err; { prcred_t cred, *cp; size_t size = sizeof (prcred_t); if (Pcred(P, &cred, 0) != 0) goto err; if (cred.pr_ngroups > 0) size += sizeof (gid_t) * (cred.pr_ngroups - 1); if ((cp = malloc(size)) == NULL) goto err; if (Pcred(P, cp, cred.pr_ngroups) != 0 || write_note(fd, NT_PRCRED, cp, size, &doff) != 0) { free(cp); goto err; } free(cp); } { prpriv_t *ppriv = NULL; const priv_impl_info_t *pinfo; size_t pprivsz, pinfosz; if (Ppriv(P, &ppriv) == -1) goto err; pprivsz = PRIV_PRPRIV_SIZE(ppriv); if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) { Ppriv_free(P, ppriv); goto err; } Ppriv_free(P, ppriv); if ((pinfo = getprivimplinfo()) == NULL) goto err; pinfosz = PRIV_IMPL_INFO_SIZE(pinfo); if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0) goto err; } if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1, &doff) != 0) goto err; { fditer_t iter; iter.fd_fd = fd; iter.fd_doff = &doff; if (Pfdinfo_iter(P, iter_fd, &iter) != 0) goto err; } { prsecflags_t *psf = NULL; if (Psecflags(P, &psf) != 0) goto err; if (write_note(fd, NT_SECFLAGS, psf, sizeof (prsecflags_t), &doff) != 0) { Psecflags_free(psf); goto err; } Psecflags_free(psf); } #if defined(__i386) || defined(__amd64) /* CSTYLED */ { struct ssd *ldtp; size_t size; int nldt; /* * Only dump out non-zero sized LDT notes. */ if ((nldt = Pldt(P, NULL, 0)) != 0) { size = sizeof (struct ssd) * nldt; if ((ldtp = malloc(size)) == NULL) goto err; if (Pldt(P, ldtp, nldt) == -1 || write_note(fd, NT_LDT, ldtp, size, &doff) != 0) { free(ldtp); goto err; } free(ldtp); } } #endif /* __i386 || __amd64 */ if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0) goto err; if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = (Elf32_Off)boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #ifdef _LP64 } else { Elf64_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #endif /* _LP64 */ } /* * Construct the headers for each mapping and write out its data * if the content parameter indicates that it should be present * in the core file. */ if (Pmapping_iter(P, dump_map, &pgc) != 0) goto err; if (dump_sections(&pgc) != 0) goto err; if (write_shstrtab(P, &pgc) != 0) goto err; free(pgc.pgc_chunk); return (0); err: /* * Wipe out anything we may have written if there was an error. */ (void) ftruncate64(fd, 0); free(pgc.pgc_chunk); return (-1); }