Example #1
0
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);
}
Example #2
0
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);
}
Example #3
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);
}