📄 pgcore.c
字号:
/* * 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 + -