⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgcore.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only. * See the file usr/src/LICENSING.NOTICE in this distribution or * http://www.opensolaris.org/license/ for details. */#pragma ident	"@(#)Pgcore.c	1.7	04/09/29 SMI"#include <stdlib.h>#include <ctype.h>#include <string.h>#include <strings.h>#include <errno.h>#include <procfs.h>#include <priv.h>#include <sys/elf.h>#include <sys/machelf.h>#include <sys/sysmacros.h>#include <sys/systeminfo.h>#include <sys/proc.h>#include <sys/utsname.h>#include <sys/old_procfs.h>#include "Pcontrol.h"#include "P32ton.h"typedef enum {	STR_CTF,	STR_SYMTAB,	STR_DYNSYM,	STR_STRTAB,	STR_DYNSTR,	STR_SHSTRTAB,	STR_NUM} shstrtype_t;static const char *shstrtab_data[] = {	".SUNW_ctf",	".symtab",	".dynsym",	".strtab",	".dynstr",	".shstrtab"};typedef struct shstrtab {	int	sst_ndx[STR_NUM];	int	sst_cur;} shstrtab_t;typedef struct {	struct ps_prochandle *P;	int		pgc_fd;	off64_t		*pgc_poff;	off64_t		*pgc_soff;	off64_t		*pgc_doff;	core_content_t	pgc_content;	void		*pgc_chunk;	size_t		pgc_chunksz;	shstrtab_t	pgc_shstrtab;} pgcore_t;static voidshstrtab_init(shstrtab_t *s){	bzero(&s->sst_ndx, sizeof (s->sst_ndx));	s->sst_cur = 1;}static intshstrtab_ndx(shstrtab_t *s, shstrtype_t type){	int ret;	if ((ret = s->sst_ndx[type]) != 0)		return (ret);	ret = s->sst_ndx[type] = s->sst_cur;	s->sst_cur += strlen(shstrtab_data[type]) + 1;	return (ret);}static size_tshstrtab_size(const shstrtab_t *s){	return (s->sst_cur);}intPgcore(struct ps_prochandle *P, const char *fname, core_content_t content){	int fd;	int err;	if ((fd = creat64(fname, 0666)) < 0)		return (-1);	if ((err = Pfgcore(P, fd, content)) != 0) {		(void) close(fd);		(void) unlink(fname);		return (err);	}	return (close(fd));}/* * Since we don't want to use the old-school procfs interfaces, we use the * new-style data structures we already have to construct the old-style * data structures. We include these data structures in core files for * backward compatability. */static voidmkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,    const lwpsinfo_t *lip, prstatus_t *psp){	bzero(psp, sizeof (*psp));	if (lsp->pr_flags & PR_STOPPED)		psp->pr_flags = 0x0001;	if (lsp->pr_flags & PR_ISTOP)		psp->pr_flags = 0x0002;	if (lsp->pr_flags & PR_DSTOP)		psp->pr_flags = 0x0004;	if (lsp->pr_flags & PR_ASLEEP)		psp->pr_flags = 0x0008;	if (lsp->pr_flags & PR_FORK)		psp->pr_flags = 0x0010;	if (lsp->pr_flags & PR_RLC)		psp->pr_flags = 0x0020;	/*	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.	 */	if (lsp->pr_flags & PR_PCINVAL)		psp->pr_flags = 0x0080;	if (lsp->pr_flags & PR_ISSYS)		psp->pr_flags = 0x0100;	if (lsp->pr_flags & PR_STEP)		psp->pr_flags = 0x0200;	if (lsp->pr_flags & PR_KLC)		psp->pr_flags = 0x0400;	if (lsp->pr_flags & PR_ASYNC)		psp->pr_flags = 0x0800;	if (lsp->pr_flags & PR_PTRACE)		psp->pr_flags = 0x1000;	if (lsp->pr_flags & PR_MSACCT)		psp->pr_flags = 0x2000;	if (lsp->pr_flags & PR_BPTADJ)		psp->pr_flags = 0x4000;	if (lsp->pr_flags & PR_ASLWP)		psp->pr_flags = 0x8000;	psp->pr_why = lsp->pr_why;	psp->pr_what = lsp->pr_what;	psp->pr_info = lsp->pr_info;	psp->pr_cursig = lsp->pr_cursig;	psp->pr_nlwp = P->status.pr_nlwp;	psp->pr_sigpend = P->status.pr_sigpend;	psp->pr_sighold = lsp->pr_lwphold;	psp->pr_altstack = lsp->pr_altstack;	psp->pr_action = lsp->pr_action;	psp->pr_pid = P->status.pr_pid;	psp->pr_ppid = P->status.pr_ppid;	psp->pr_pgrp = P->status.pr_pgid;	psp->pr_sid = P->status.pr_sid;	psp->pr_utime = P->status.pr_utime;	psp->pr_stime = P->status.pr_stime;	psp->pr_cutime = P->status.pr_cutime;	psp->pr_cstime = P->status.pr_cstime;	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));	psp->pr_syscall = lsp->pr_syscall;	psp->pr_nsysarg = lsp->pr_nsysarg;	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));	psp->pr_who = lsp->pr_lwpid;	psp->pr_lwppend = lsp->pr_lwppend;	psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;	psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;	psp->pr_brksize = P->status.pr_brksize;	psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;	psp->pr_stksize = P->status.pr_stksize;	psp->pr_processor = (short)lip->pr_onpro;	psp->pr_bind = (short)lip->pr_bindpro;	psp->pr_instr = lsp->pr_instr;	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));}static voidmkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp){	bzero(psp, sizeof (*psp));	psp->pr_state = P->psinfo.pr_lwp.pr_state;	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;	psp->pr_zomb = (psp->pr_state == SZOMB);	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;	psp->pr_uid = P->psinfo.pr_uid;	psp->pr_gid = P->psinfo.pr_gid;	psp->pr_pid = P->psinfo.pr_pid;	psp->pr_ppid = P->psinfo.pr_ppid;	psp->pr_pgrp = P->psinfo.pr_pgid;	psp->pr_sid = P->psinfo.pr_sid;	psp->pr_addr = (caddr_t)P->psinfo.pr_addr;	psp->pr_size = P->psinfo.pr_size;	psp->pr_rssize = P->psinfo.pr_rssize;	psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;	psp->pr_start = P->psinfo.pr_start;	psp->pr_time = P->psinfo.pr_time;	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);	psp->pr_lttydev = P->psinfo.pr_ttydev;	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,	    sizeof (psp->pr_clname));	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,	    sizeof (psp->pr_fname));	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,	    sizeof (psp->pr_psargs));	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;	psp->pr_ctime = P->psinfo.pr_ctime;	psp->pr_bysize = psp->pr_size * PAGESIZE;	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;	psp->pr_argc = P->psinfo.pr_argc;	psp->pr_argv = (char **)P->psinfo.pr_argv;	psp->pr_envp = (char **)P->psinfo.pr_envp;	psp->pr_wstat = P->psinfo.pr_wstat;	psp->pr_pctcpu = P->psinfo.pr_pctcpu;	psp->pr_pctmem = P->psinfo.pr_pctmem;	psp->pr_euid = P->psinfo.pr_euid;	psp->pr_egid = P->psinfo.pr_egid;	psp->pr_aslwpid = 0;	psp->pr_dmodel = P->psinfo.pr_dmodel;}#ifdef _LP64static voidmkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,    const lwpsinfo_t *lip, prstatus32_t *psp){	bzero(psp, sizeof (*psp));	if (lsp->pr_flags & PR_STOPPED)		psp->pr_flags = 0x0001;	if (lsp->pr_flags & PR_ISTOP)		psp->pr_flags = 0x0002;	if (lsp->pr_flags & PR_DSTOP)		psp->pr_flags = 0x0004;	if (lsp->pr_flags & PR_ASLEEP)		psp->pr_flags = 0x0008;	if (lsp->pr_flags & PR_FORK)		psp->pr_flags = 0x0010;	if (lsp->pr_flags & PR_RLC)		psp->pr_flags = 0x0020;	/*	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.	 */	if (lsp->pr_flags & PR_PCINVAL)		psp->pr_flags = 0x0080;	if (lsp->pr_flags & PR_ISSYS)		psp->pr_flags = 0x0100;	if (lsp->pr_flags & PR_STEP)		psp->pr_flags = 0x0200;	if (lsp->pr_flags & PR_KLC)		psp->pr_flags = 0x0400;	if (lsp->pr_flags & PR_ASYNC)		psp->pr_flags = 0x0800;	if (lsp->pr_flags & PR_PTRACE)		psp->pr_flags = 0x1000;	if (lsp->pr_flags & PR_MSACCT)		psp->pr_flags = 0x2000;	if (lsp->pr_flags & PR_BPTADJ)		psp->pr_flags = 0x4000;	if (lsp->pr_flags & PR_ASLWP)		psp->pr_flags = 0x8000;	psp->pr_why = lsp->pr_why;	psp->pr_what = lsp->pr_what;	siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);	psp->pr_cursig = lsp->pr_cursig;	psp->pr_nlwp = P->status.pr_nlwp;	psp->pr_sigpend = P->status.pr_sigpend;	psp->pr_sighold = lsp->pr_lwphold;	stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);	sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);	psp->pr_pid = P->status.pr_pid;	psp->pr_ppid = P->status.pr_ppid;	psp->pr_pgrp = P->status.pr_pgid;	psp->pr_sid = P->status.pr_sid;	timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);	timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);	timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);	timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));	psp->pr_syscall = lsp->pr_syscall;	psp->pr_nsysarg = lsp->pr_nsysarg;	bcopy(lsp->pr_sysarg, psp->pr_sysarg,	    sizeof (psp->pr_sysarg)); psp->pr_who = lsp->pr_lwpid;	psp->pr_lwppend = lsp->pr_lwppend;	psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;	psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;	psp->pr_brksize = P->status.pr_brksize;	psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;	psp->pr_stksize = P->status.pr_stksize;	psp->pr_processor = (short)lip->pr_onpro;	psp->pr_bind = (short)lip->pr_bindpro;	psp->pr_instr = lsp->pr_instr;	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));}static voidmkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp){	bzero(psp, sizeof (*psp));	psp->pr_state = P->psinfo.pr_lwp.pr_state;	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;	psp->pr_zomb = (psp->pr_state == SZOMB);	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;	psp->pr_uid = P->psinfo.pr_uid;	psp->pr_gid = P->psinfo.pr_gid;	psp->pr_pid = P->psinfo.pr_pid;	psp->pr_ppid = P->psinfo.pr_ppid;	psp->pr_pgrp = P->psinfo.pr_pgid;	psp->pr_sid = P->psinfo.pr_sid;	psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;	psp->pr_size = P->psinfo.pr_size;	psp->pr_rssize = P->psinfo.pr_rssize;	psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;	timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);	timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);	psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,	    sizeof (psp->pr_clname));	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,	    sizeof (psp->pr_fname));	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,	    sizeof (psp->pr_psargs));	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;	timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);	psp->pr_bysize = psp->pr_size * PAGESIZE;	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;	psp->pr_argc = P->psinfo.pr_argc;	psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;	psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;	psp->pr_wstat = P->psinfo.pr_wstat;	psp->pr_pctcpu = P->psinfo.pr_pctcpu;	psp->pr_pctmem = P->psinfo.pr_pctmem;	psp->pr_euid = P->psinfo.pr_euid;	psp->pr_egid = P->psinfo.pr_egid;	psp->pr_aslwpid = 0;	psp->pr_dmodel = P->psinfo.pr_dmodel;}#endif	/* _LP64 */static intwrite_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp){	/*	 * Note headers are the same regardless of the data model of the	 * ELF file; we arbitrarily use Elf64_Nhdr here.	 */	struct {		Elf64_Nhdr nhdr;		char name[8];	} n;	bzero(&n, sizeof (n));	bcopy("CORE", n.name, 4);	n.nhdr.n_type = type;	n.nhdr.n_namesz = 5;	n.nhdr.n_descsz = roundup(descsz, 4);	if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n))		return (-1);	*offp += sizeof (n);	if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz)		return (-1);	*offp += n.nhdr.n_descsz;	return (0);}static intold_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip){	pgcore_t *pgc = data;	struct ps_prochandle *P = pgc->P;	/*	 * Legacy core files don't contain information about zombie LWPs.	 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure	 * more cheaply.	 */	if (lsp == NULL)		return (0);	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {		prstatus_t prstatus;		mkprstatus(P, lsp, lip, &prstatus);		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,		    sizeof (prstatus_t), pgc->pgc_doff) != 0)			return (0);		if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,		    sizeof (prfpregset_t), pgc->pgc_doff) != 0)			return (1);#ifdef _LP64	} else {		prstatus32_t pr32;		prfpregset32_t pf32;		mkprstatus32(P, lsp, lip, &pr32);		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,		    sizeof (prstatus32_t), pgc->pgc_doff) != 0)			return (1);		prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);		if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,		    sizeof (prfpregset32_t), pgc->pgc_doff) != 0)			return (1);#endif	/* _LP64 */	}#ifdef sparc	{		prxregset_t xregs;		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 &&		    write_note(pgc->pgc_fd, NT_PRXREG, &xregs,		    sizeof (prxregset_t), pgc->pgc_doff) != 0)			return (1);	}#endif	/* sparc */	return (0);}static intnew_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip){	pgcore_t *pgc = data;	struct ps_prochandle *P = pgc->P;	/*	 * If lsp is NULL this indicates that this is a zombie LWP in	 * which case we dump only the lwpsinfo_t structure and none of	 * the other ancillary LWP state data.	 */	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {		if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,		    sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)			return (1);		if (lsp == NULL)			return (0);		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,		    sizeof (lwpstatus_t), pgc->pgc_doff) != 0)			return (1);#ifdef _LP64	} else {		lwpsinfo32_t li32;		lwpstatus32_t ls32;		lwpsinfo_n_to_32(lip, &li32);		if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,		    sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)			return (1);		if (lsp == NULL)			return (0);		lwpstatus_n_to_32(lsp, &ls32);		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,		    sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)			return (1);#endif	/* _LP64 */	}#ifdef sparc	{		prxregset_t xregs;		gwindows_t gwins;		size_t size;		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) {			if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs,			    sizeof (prxregset_t), pgc->pgc_doff) != 0)				return (1);		}		if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 &&		    gwins.wbcnt > 0) {			size = sizeof (gwins) - sizeof (gwins.wbuf) +			    gwins.wbcnt * sizeof (gwins.wbuf[0]);			if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -