Additionally: Differential Revision: https://reviews.freebsd.org/D9995
Tycho > On Mar 30, 2017, at 2:21 PM, Tycho Nightingale <tyc...@freebsd.org> wrote: > > Author: tychon > Date: Thu Mar 30 18:21:36 2017 > New Revision: 316286 > URL: https://svnweb.freebsd.org/changeset/base/316286 > > Log: > Add support for capturing 'struct ptrace_lwpinfo' for signals > resulting in a process dumping core in the corefile. > > Also extend procstat to view select members of 'struct ptrace_lwpinfo' > from the contents of the note. > > Sponsored by: Dell EMC Isilon > > Added: > head/usr.bin/procstat/procstat_ptlwpinfo.c (contents, props changed) > Modified: > head/lib/libprocstat/Symbol.map > head/lib/libprocstat/core.c > head/lib/libprocstat/core.h > head/lib/libprocstat/libprocstat.c > head/lib/libprocstat/libprocstat.h > head/sys/kern/imgact_elf.c > head/sys/kern/kern_sig.c > head/sys/kern/sys_process.c > head/sys/sys/elf_common.h > head/sys/sys/proc.h > head/usr.bin/gcore/elfcore.c > head/usr.bin/procstat/Makefile > head/usr.bin/procstat/procstat.1 > head/usr.bin/procstat/procstat.c > head/usr.bin/procstat/procstat.h > > Modified: head/lib/libprocstat/Symbol.map > ============================================================================== > --- head/lib/libprocstat/Symbol.map Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/lib/libprocstat/Symbol.map Thu Mar 30 18:21:36 2017 > (r316286) > @@ -36,3 +36,8 @@ FBSD_1.3 { > procstat_getvmmap; > procstat_open_core; > }; > + > +FBSD_1.5 { > + procstat_freeptlwpinfo; > + procstat_getptlwpinfo; > +}; > > Modified: head/lib/libprocstat/core.c > ============================================================================== > --- head/lib/libprocstat/core.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/lib/libprocstat/core.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,5 +1,6 @@ > /*- > * Copyright (c) 2013 Mikolaj Golub <troc...@freebsd.org> > + * Copyright (c) 2017 Dell EMC > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -30,6 +31,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/param.h> > #include <sys/elf.h> > #include <sys/exec.h> > +#include <sys/ptrace.h> > #include <sys/user.h> > > #include <assert.h> > @@ -56,6 +58,24 @@ struct procstat_core > GElf_Phdr pc_phdr; > }; > > +static struct psc_type_info { > + unsigned int n_type; > + int structsize; > +} psc_type_info[PSC_TYPE_MAX] = { > + { .n_type = NT_PROCSTAT_PROC, .structsize = sizeof(struct kinfo_proc) > }, > + { .n_type = NT_PROCSTAT_FILES, .structsize = sizeof(struct kinfo_file) > }, > + { .n_type = NT_PROCSTAT_VMMAP, .structsize = sizeof(struct > kinfo_vmentry) }, > + { .n_type = NT_PROCSTAT_GROUPS, .structsize = sizeof(gid_t) }, > + { .n_type = NT_PROCSTAT_UMASK, .structsize = sizeof(u_short) }, > + { .n_type = NT_PROCSTAT_RLIMIT, .structsize = sizeof(struct rlimit) * > RLIM_NLIMITS }, > + { .n_type = NT_PROCSTAT_OSREL, .structsize = sizeof(int) }, > + { .n_type = NT_PROCSTAT_PSSTRINGS, .structsize = sizeof(vm_offset_t) }, > + { .n_type = NT_PROCSTAT_PSSTRINGS, .structsize = sizeof(vm_offset_t) }, > + { .n_type = NT_PROCSTAT_PSSTRINGS, .structsize = sizeof(vm_offset_t) }, > + { .n_type = NT_PROCSTAT_AUXV, .structsize = sizeof(Elf_Auxinfo) }, > + { .n_type = NT_PTLWPINFO, .structsize = sizeof(struct ptrace_lwpinfo) }, > +}; > + > static bool core_offset(struct procstat_core *core, off_t offset); > static bool core_read(struct procstat_core *core, void *buf, size_t len); > static ssize_t core_read_mem(struct procstat_core *core, void *buf, > @@ -154,59 +174,20 @@ procstat_core_get(struct procstat_core * > off_t offset, eoffset; > vm_offset_t psstrings; > void *freebuf; > - size_t len; > - u_int32_t n_type; > - int cstructsize, structsize; > + size_t len, curlen; > + int cstructsize; > char nbuf[8]; > > assert(core->pc_magic == PROCSTAT_CORE_MAGIC); > > - switch(type) { > - case PSC_TYPE_PROC: > - n_type = NT_PROCSTAT_PROC; > - structsize = sizeof(struct kinfo_proc); > - break; > - case PSC_TYPE_FILES: > - n_type = NT_PROCSTAT_FILES; > - structsize = sizeof(struct kinfo_file); > - break; > - case PSC_TYPE_VMMAP: > - n_type = NT_PROCSTAT_VMMAP; > - structsize = sizeof(struct kinfo_vmentry); > - break; > - case PSC_TYPE_GROUPS: > - n_type = NT_PROCSTAT_GROUPS; > - structsize = sizeof(gid_t); > - break; > - case PSC_TYPE_UMASK: > - n_type = NT_PROCSTAT_UMASK; > - structsize = sizeof(u_short); > - break; > - case PSC_TYPE_RLIMIT: > - n_type = NT_PROCSTAT_RLIMIT; > - structsize = sizeof(struct rlimit) * RLIM_NLIMITS; > - break; > - case PSC_TYPE_OSREL: > - n_type = NT_PROCSTAT_OSREL; > - structsize = sizeof(int); > - break; > - case PSC_TYPE_PSSTRINGS: > - case PSC_TYPE_ARGV: > - case PSC_TYPE_ENVV: > - n_type = NT_PROCSTAT_PSSTRINGS; > - structsize = sizeof(vm_offset_t); > - break; > - case PSC_TYPE_AUXV: > - n_type = NT_PROCSTAT_AUXV; > - structsize = sizeof(Elf_Auxinfo); > - break; > - default: > + if (type >= PSC_TYPE_MAX) { > warnx("unknown core stat type: %d", type); > return (NULL); > } > > offset = core->pc_phdr.p_offset; > eoffset = offset + core->pc_phdr.p_filesz; > + curlen = 0; > > while (offset < eoffset) { > if (!core_offset(core, offset)) > @@ -220,7 +201,7 @@ procstat_core_get(struct procstat_core * > > if (nhdr.n_namesz == 0 && nhdr.n_descsz == 0) > break; > - if (nhdr.n_type != n_type) > + if (nhdr.n_type != psc_type_info[type].n_type) > continue; > if (nhdr.n_namesz != 8) > continue; > @@ -234,7 +215,7 @@ procstat_core_get(struct procstat_core * > } > if (!core_read(core, &cstructsize, sizeof(cstructsize))) > return (NULL); > - if (cstructsize != structsize) { > + if (cstructsize != psc_type_info[type].structsize) { > warnx("version mismatch"); > return (NULL); > } > @@ -251,7 +232,7 @@ procstat_core_get(struct procstat_core * > return (NULL); > } > } > - if (!core_read(core, buf, len)) { > + if (!core_read(core, (char *)buf + curlen, len)) { > free(freebuf); > return (NULL); > } > @@ -267,11 +248,20 @@ procstat_core_get(struct procstat_core * > buf = NULL; > free(freebuf); > buf = get_args(core, psstrings, type, buf, &len); > + } else if (type == PSC_TYPE_PTLWPINFO) { > + *lenp -= len; > + curlen += len; > + continue; > } > *lenp = len; > return (buf); > } > > + if (curlen != 0) { > + *lenp = curlen; > + return (buf); > + } > + > return (NULL); > } > > @@ -431,3 +421,57 @@ done: > free(argv); > return (args); > } > + > +int > +procstat_core_note_count(struct procstat_core *core, enum psc_type type) > +{ > + Elf_Note nhdr; > + off_t offset, eoffset; > + int cstructsize; > + char nbuf[8]; > + int n; > + > + if (type >= PSC_TYPE_MAX) { > + warnx("unknown core stat type: %d", type); > + return (0); > + } > + > + offset = core->pc_phdr.p_offset; > + eoffset = offset + core->pc_phdr.p_filesz; > + > + for (n = 0; offset < eoffset; n++) { > + if (!core_offset(core, offset)) > + return (0); > + if (!core_read(core, &nhdr, sizeof(nhdr))) > + return (0); > + > + offset += sizeof(nhdr) + > + roundup2(nhdr.n_namesz, sizeof(Elf32_Size)) + > + roundup2(nhdr.n_descsz, sizeof(Elf32_Size)); > + > + if (nhdr.n_namesz == 0 && nhdr.n_descsz == 0) > + break; > + if (nhdr.n_type != psc_type_info[type].n_type) > + continue; > + if (nhdr.n_namesz != 8) > + continue; > + if (!core_read(core, nbuf, sizeof(nbuf))) > + return (0); > + if (strcmp(nbuf, "FreeBSD") != 0) > + continue; > + if (nhdr.n_descsz < sizeof(cstructsize)) { > + warnx("corrupted core file"); > + return (0); > + } > + if (!core_read(core, &cstructsize, sizeof(cstructsize))) > + return (0); > + if (cstructsize != psc_type_info[type].structsize) { > + warnx("version mismatch"); > + return (0); > + } > + if (nhdr.n_descsz - sizeof(cstructsize) == 0) > + return (0); > + } > + > + return (n); > +} > > Modified: head/lib/libprocstat/core.h > ============================================================================== > --- head/lib/libprocstat/core.h Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/lib/libprocstat/core.h Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,5 +1,6 @@ > /*- > * Copyright (c) 2013 Mikolaj Golub <troc...@freebsd.org> > + * Copyright (c) 2017 Dell EMC > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -41,6 +42,8 @@ enum psc_type { > PSC_TYPE_ARGV, > PSC_TYPE_ENVV, > PSC_TYPE_AUXV, > + PSC_TYPE_PTLWPINFO, > + PSC_TYPE_MAX > }; > > struct procstat_core; > @@ -48,6 +51,7 @@ struct procstat_core; > void procstat_core_close(struct procstat_core *core); > void *procstat_core_get(struct procstat_core *core, enum psc_type type, > void * buf, size_t *lenp); > +int procstat_core_note_count(struct procstat_core *core, enum psc_type type); > struct procstat_core *procstat_core_open(const char *filename); > > #endif /* !_CORE_H_ */ > > Modified: head/lib/libprocstat/libprocstat.c > ============================================================================== > --- head/lib/libprocstat/libprocstat.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/lib/libprocstat/libprocstat.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,4 +1,5 @@ > /*- > + * Copyright (c) 2017 Dell EMC > * Copyright (c) 2009 Stanislav Sedov <s...@freebsd.org> > * Copyright (c) 1988, 1993 > * The Regents of the University of California. All rights reserved. > @@ -65,6 +66,7 @@ __FBSDID("$FreeBSD$"); > #define _KERNEL > #include <sys/mount.h> > #include <sys/pipe.h> > +#include <sys/ptrace.h> > #include <ufs/ufs/quota.h> > #include <ufs/ufs/inode.h> > #include <fs/devfs/devfs.h> > @@ -2470,6 +2472,48 @@ procstat_freeauxv(struct procstat *procs > free(auxv); > } > > +static struct ptrace_lwpinfo * > +procstat_getptlwpinfo_core(struct procstat_core *core, unsigned int *cntp) > +{ > + void *buf; > + struct ptrace_lwpinfo *pl; > + unsigned int cnt; > + size_t len; > + > + cnt = procstat_core_note_count(core, PSC_TYPE_PTLWPINFO); > + if (cnt == 0) > + return (NULL); > + > + len = cnt * sizeof(*pl); > + buf = calloc(1, len); > + pl = procstat_core_get(core, PSC_TYPE_PTLWPINFO, buf, &len); > + if (pl == NULL) { > + free(buf); > + return (NULL); > + } > + *cntp = len / sizeof(*pl); > + return (pl); > +} > + > +struct ptrace_lwpinfo * > +procstat_getptlwpinfo(struct procstat *procstat, unsigned int *cntp) > +{ > + switch (procstat->type) { > + case PROCSTAT_CORE: > + return (procstat_getptlwpinfo_core(procstat->core, cntp)); > + default: > + warnx("unknown access method: %d", procstat->type); > + return (NULL); > + } > +} > + > +void > +procstat_freeptlwpinfo(struct procstat *procstat __unused, > + struct ptrace_lwpinfo *pl) > +{ > + free(pl); > +} > + > static struct kinfo_kstack * > procstat_getkstack_sysctl(pid_t pid, int *cntp) > { > > Modified: head/lib/libprocstat/libprocstat.h > ============================================================================== > --- head/lib/libprocstat/libprocstat.h Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/lib/libprocstat/libprocstat.h Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,5 +1,6 @@ > /*- > * Copyright (c) 2009 Stanislav Sedov <s...@freebsd.org> > + * Copyright (c) 2017 Dell EMC > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -101,6 +102,7 @@ > struct kinfo_kstack; > struct kinfo_vmentry; > struct procstat; > +struct ptrace_lwpinfo; > struct rlimit; > struct filestat { > int fs_type; /* Descriptor type. */ > @@ -172,6 +174,8 @@ void procstat_freekstack(struct procstat > void procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p); > void procstat_freefiles(struct procstat *procstat, > struct filestat_list *head); > +void procstat_freeptlwpinfo(struct procstat *procstat, > + struct ptrace_lwpinfo *pl); > void procstat_freevmmap(struct procstat *procstat, > struct kinfo_vmentry *vmmap); > struct filestat_list *procstat_getfiles(struct procstat *procstat, > @@ -196,6 +200,8 @@ char **procstat_getargv(struct procstat > Elf_Auxinfo *procstat_getauxv(struct procstat *procstat, > struct kinfo_proc *kp, unsigned int *cntp); > #endif > +struct ptrace_lwpinfo *procstat_getptlwpinfo(struct procstat > *procstat, > + unsigned int *cntp); > char **procstat_getenvv(struct procstat *procstat, struct kinfo_proc *p, > size_t nchr); > gid_t *procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp, > > Modified: head/sys/kern/imgact_elf.c > ============================================================================== > --- head/sys/kern/imgact_elf.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/sys/kern/imgact_elf.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,4 +1,5 @@ > /*- > + * Copyright (c) 2017 Dell EMC > * Copyright (c) 2000 David O'Brien > * Copyright (c) 1995-1996 Søren Schmidt > * Copyright (c) 1996 Peter Wemm > @@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/pioctl.h> > #include <sys/proc.h> > #include <sys/procfs.h> > +#include <sys/ptrace.h> > #include <sys/racct.h> > #include <sys/resourcevar.h> > #include <sys/rwlock.h> > @@ -1202,6 +1204,7 @@ static void __elfN(note_prpsinfo)(void * > static void __elfN(note_prstatus)(void *, struct sbuf *, size_t *); > static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *); > static void __elfN(note_thrmisc)(void *, struct sbuf *, size_t *); > +static void __elfN(note_ptlwpinfo)(void *, struct sbuf *, size_t *); > static void __elfN(note_procstat_auxv)(void *, struct sbuf *, size_t *); > static void __elfN(note_procstat_proc)(void *, struct sbuf *, size_t *); > static void __elfN(note_procstat_psstrings)(void *, struct sbuf *, size_t *); > @@ -1628,6 +1631,8 @@ __elfN(prepare_notes)(struct thread *td, > __elfN(note_fpregset), thr); > size += register_note(list, NT_THRMISC, > __elfN(note_thrmisc), thr); > + size += register_note(list, NT_PTLWPINFO, > + __elfN(note_ptlwpinfo), thr); > size += register_note(list, -1, > __elfN(note_threadmd), thr); > > @@ -2018,6 +2023,37 @@ __elfN(note_thrmisc)(void *arg, struct s > *sizep = sizeof(thrmisc); > } > > +static void > +__elfN(note_ptlwpinfo)(void *arg, struct sbuf *sb, size_t *sizep) > +{ > + struct thread *td; > + size_t size; > + int structsize; > + struct ptrace_lwpinfo pl; > + > + td = (struct thread *)arg; > + size = sizeof(structsize) + sizeof(struct ptrace_lwpinfo); > + if (sb != NULL) { > + KASSERT(*sizep == size, ("invalid size")); > + structsize = sizeof(struct ptrace_lwpinfo); > + sbuf_bcat(sb, &structsize, sizeof(structsize)); > + bzero(&pl, sizeof(pl)); > + pl.pl_lwpid = td->td_tid; > + pl.pl_event = PL_EVENT_NONE; > + pl.pl_sigmask = td->td_sigmask; > + pl.pl_siglist = td->td_siglist; > + if (td->td_si.si_signo != 0) { > + pl.pl_event = PL_EVENT_SIGNAL; > + pl.pl_flags |= PL_FLAG_SI; > + pl.pl_siginfo = td->td_si; > + } > + strcpy(pl.pl_tdname, td->td_name); > + /* XXX TODO: supply more information in struct ptrace_lwpinfo*/ > + sbuf_bcat(sb, &pl, sizeof(struct ptrace_lwpinfo)); > + } > + *sizep = size; > +} > + > /* > * Allow for MD specific notes, as well as any MD > * specific preparations for writing MI notes. > > Modified: head/sys/kern/kern_sig.c > ============================================================================== > --- head/sys/kern/kern_sig.c Thu Mar 30 18:20:04 2017 (r316285) > +++ head/sys/kern/kern_sig.c Thu Mar 30 18:21:36 2017 (r316286) > @@ -1226,6 +1226,19 @@ sys_sigwaitinfo(struct thread *td, struc > return (error); > } > > +static void > +proc_td_siginfo_capture(struct thread *td, siginfo_t *si) > +{ > + struct thread *thr; > + > + FOREACH_THREAD_IN_PROC(td->td_proc, thr) { > + if (thr == td) > + thr->td_si = *si; > + else > + thr->td_si.si_signo = 0; > + } > +} > + > int > kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, > struct timespec *timeout) > @@ -1334,8 +1347,10 @@ kern_sigtimedwait(struct thread *td, sig > ktrpsig(sig, action, &td->td_sigmask, ksi->ksi_code); > } > #endif > - if (sig == SIGKILL) > + if (sig == SIGKILL) { > + proc_td_siginfo_capture(td, &ksi->ksi_info); > sigexit(td, sig); > + } > } > PROC_UNLOCK(p); > return (error); > @@ -2756,6 +2771,7 @@ issignal(struct thread *td) > struct sigqueue *queue; > sigset_t sigpending; > int sig, prop; > + ksiginfo_t ksi; > > p = td->td_proc; > ps = p->p_sigacts; > @@ -2811,14 +2827,15 @@ issignal(struct thread *td) > * be thrown away. > */ > queue = &td->td_sigqueue; > - td->td_dbgksi.ksi_signo = 0; > - if (sigqueue_get(queue, sig, &td->td_dbgksi) == 0) { > + ksiginfo_init(&ksi); > + if (sigqueue_get(queue, sig, &ksi) == 0) { > queue = &p->p_sigqueue; > - sigqueue_get(queue, sig, &td->td_dbgksi); > + sigqueue_get(queue, sig, &ksi); > } > + td->td_si = ksi.ksi_info; > > mtx_unlock(&ps->ps_mtx); > - sig = ptracestop(td, sig, &td->td_dbgksi); > + sig = ptracestop(td, sig, &ksi); > mtx_lock(&ps->ps_mtx); > > /* > @@ -2989,6 +3006,7 @@ postsig(sig) > * the process. (Other cases were ignored above.) > */ > mtx_unlock(&ps->ps_mtx); > + proc_td_siginfo_capture(td, &ksi.ksi_info); > sigexit(td, sig); > /* NOTREACHED */ > } else { > > Modified: head/sys/kern/sys_process.c > ============================================================================== > --- head/sys/kern/sys_process.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/sys/kern/sys_process.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1306,7 +1306,7 @@ kern_ptrace(struct thread *td, int req, > pl->pl_flags = 0; > if (td2->td_dbgflags & TDB_XSIG) { > pl->pl_event = PL_EVENT_SIGNAL; > - if (td2->td_dbgksi.ksi_signo != 0 && > + if (td2->td_si.si_signo != 0 && > #ifdef COMPAT_FREEBSD32 > ((!wrap32 && data >= offsetof(struct ptrace_lwpinfo, > pl_siginfo) + sizeof(pl->pl_siginfo)) || > @@ -1318,7 +1318,7 @@ kern_ptrace(struct thread *td, int req, > #endif > ){ > pl->pl_flags |= PL_FLAG_SI; > - pl->pl_siginfo = td2->td_dbgksi.ksi_info; > + pl->pl_siginfo = td2->td_si; > } > } > if ((pl->pl_flags & PL_FLAG_SI) == 0) > > Modified: head/sys/sys/elf_common.h > ============================================================================== > --- head/sys/sys/elf_common.h Thu Mar 30 18:20:04 2017 (r316285) > +++ head/sys/sys/elf_common.h Thu Mar 30 18:21:36 2017 (r316286) > @@ -1,4 +1,5 @@ > /*- > + * Copyright (c) 2017 Dell EMC > * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien > * Copyright (c) 1998 John D. Polstra. > * All rights reserved. > @@ -753,6 +754,7 @@ typedef struct { > #define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ > #define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ > #define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */ > +#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous > info. */ > #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ > #define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */ > > > Modified: head/sys/sys/proc.h > ============================================================================== > --- head/sys/sys/proc.h Thu Mar 30 18:20:04 2017 (r316285) > +++ head/sys/sys/proc.h Thu Mar 30 18:21:36 2017 (r316286) > @@ -274,7 +274,7 @@ struct thread { > char td_name[MAXCOMLEN + 1]; /* (*) Thread name. */ > struct file *td_fpop; /* (k) file referencing cdev under op */ > int td_dbgflags; /* (c) Userland debugger flags */ > - struct ksiginfo td_dbgksi; /* (c) ksi reflected to debugger. */ > + siginfo_t td_si; /* (c) For debugger or core file */ > int td_ng_outbound; /* (k) Thread entered ng from above. */ > struct osd td_osd; /* (k) Object specific data. */ > struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */ > > Modified: head/usr.bin/gcore/elfcore.c > ============================================================================== > --- head/usr.bin/gcore/elfcore.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/usr.bin/gcore/elfcore.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,4 +1,5 @@ > /*- > + * Copyright (c) 2017 Dell EMC > * Copyright (c) 2007 Sandvine Incorporated > * Copyright (c) 1998 John D. Polstra > * All rights reserved. > @@ -102,6 +103,7 @@ static void *elf_note_fpregset(void *, s > static void *elf_note_prpsinfo(void *, size_t *); > static void *elf_note_prstatus(void *, size_t *); > static void *elf_note_thrmisc(void *, size_t *); > +static void *elf_note_ptlwpinfo(void *, size_t *); > #if defined(__i386__) || defined(__amd64__) > static void *elf_note_x86_xstate(void *, size_t *); > #endif > @@ -360,6 +362,7 @@ elf_putnotes(pid_t pid, struct sbuf *sb, > elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb); > elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); > elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); > + elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb); > #if defined(__i386__) || defined(__amd64__) > elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb); > #endif > @@ -689,6 +692,24 @@ elf_note_thrmisc(void *arg, size_t *size > return (thrmisc); > } > > +static void * > +elf_note_ptlwpinfo(void *arg, size_t *sizep) > +{ > + lwpid_t tid; > + void *p; > + > + tid = *(lwpid_t *)arg; > + p = calloc(1, sizeof(int) + sizeof(struct ptrace_lwpinfo)); > + if (p == NULL) > + errx(1, "out of memory"); > + *(int *)p = sizeof(struct ptrace_lwpinfo); > + ptrace(PT_LWPINFO, tid, > + (char *)p + sizeof (int), sizeof(struct ptrace_lwpinfo)); > + > + *sizep = sizeof(int) + sizeof(struct ptrace_lwpinfo); > + return (p); > +} > + > #if defined(__i386__) || defined(__amd64__) > static void * > elf_note_x86_xstate(void *arg, size_t *sizep) > > Modified: head/usr.bin/procstat/Makefile > ============================================================================== > --- head/usr.bin/procstat/Makefile Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/usr.bin/procstat/Makefile Thu Mar 30 18:21:36 2017 > (r316286) > @@ -11,6 +11,7 @@ SRCS= procstat.c \ > procstat_cs.c \ > procstat_files.c \ > procstat_kstack.c \ > + procstat_ptlwpinfo.c \ > procstat_rlimit.c \ > procstat_rusage.c \ > procstat_sigs.c \ > > Modified: head/usr.bin/procstat/procstat.1 > ============================================================================== > --- head/usr.bin/procstat/procstat.1 Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/usr.bin/procstat/procstat.1 Thu Mar 30 18:21:36 2017 > (r316286) > @@ -36,7 +36,7 @@ > .Op Fl -libxo > .Op Fl CHhn > .Op Fl w Ar interval > -.Op Fl b | c | e | f | i | j | k | l | r | s | S | t | v | x > +.Op Fl b | c | e | f | i | j | k | l | L | r | s | S | t | v | x > .Op Fl a | Ar pid | Ar core ... > .Sh DESCRIPTION > The > @@ -79,6 +79,8 @@ If the flag is repeated, function offset > printed. > .It Fl l > Display resource limits for the process. > +.It Fl L > +Display LWP info for the process pertaining to it's signal driven exit. > .It Fl r > Display resource usage information for the process. > .It Fl s > > Modified: head/usr.bin/procstat/procstat.c > ============================================================================== > --- head/usr.bin/procstat/procstat.c Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/usr.bin/procstat/procstat.c Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,6 +1,7 @@ > /*- > * Copyright (c) 2007, 2011 Robert N. M. Watson > * Copyright (c) 2015 Allan Jude <allanj...@freebsd.org> > + * Copyright (c) 2017 Dell EMC > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -41,8 +42,8 @@ > > #include "procstat.h" > > -static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, > rflag; > -static int sflag, tflag, vflag, xflag, Sflag; > +static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag; > +static int lflag, Lflag, rflag, sflag, tflag, vflag, xflag, Sflag; > int hflag, nflag, Cflag, Hflag; > > static void > @@ -84,6 +85,8 @@ procstat(struct procstat *prstat, struct > procstat_kstack(prstat, kipp, kflag); > else if (lflag) > procstat_rlimit(prstat, kipp); > + else if (Lflag) > + procstat_ptlwpinfo(prstat); > else if (rflag) > procstat_rusage(prstat, kipp); > else if (sflag) > @@ -161,7 +164,7 @@ main(int argc, char *argv[]) > argc = xo_parse_args(argc, argv); > xocontainer = "basic"; > > - while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) { > + while ((ch = getopt(argc, argv, "CHN:M:abcefijklLhrsStvw:x")) != -1) { > switch (ch) { > case 'C': > Cflag++; > @@ -225,6 +228,11 @@ main(int argc, char *argv[]) > xocontainer = "rlimit"; > break; > > + case 'L': > + Lflag++; > + xocontainer = "ptlwpinfo"; > + break; > + > case 'n': > nflag++; > break; > > Modified: head/usr.bin/procstat/procstat.h > ============================================================================== > --- head/usr.bin/procstat/procstat.h Thu Mar 30 18:20:04 2017 > (r316285) > +++ head/usr.bin/procstat/procstat.h Thu Mar 30 18:21:36 2017 > (r316286) > @@ -1,6 +1,7 @@ > /*- > * Copyright (c) 2007 Robert N. M. Watson > * Copyright (c) 2015 Allan Jude <allanj...@freebsd.org> > + * Copyright (c) 2017 Dell EMC > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -50,6 +51,7 @@ void procstat_env(struct procstat *prsta > void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp); > void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp, > int kflag); > +void procstat_ptlwpinfo(struct procstat *prstat); > void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp); > void procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp); > void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp); > > Added: head/usr.bin/procstat/procstat_ptlwpinfo.c > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/usr.bin/procstat/procstat_ptlwpinfo.c Thu Mar 30 18:21:36 > 2017 (r316286) > @@ -0,0 +1,91 @@ > +/*- > + * Copyright (c) 2017 Dell EMC > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + * > + */ > + #include <sys/cdefs.h> > + __FBSDID("$FreeBSD$"); > + > +#include <sys/param.h> > +#include <sys/ptrace.h> > +#include <sys/user.h> > + > +#include <libprocstat.h> > + > +#include "procstat.h" > + > +void > +procstat_ptlwpinfo(struct procstat *prstat) > +{ > + struct ptrace_lwpinfo *pl; > + unsigned int count, i; > + > + pl = procstat_getptlwpinfo(prstat, &count); > + if (pl == NULL) > + return; > + > + if (!hflag) > + xo_emit("{:/%6s %7s %5s %5s %5s %6s %5s} {[:/%d}{:/%s}{]:}" > + " {:/%s}\n", > + "LWPID", "EVENT", "SIGNO", "CODE", "ERRNO", "PID", "UID", > + 2 * sizeof(void *) + 2, "ADDR", "TDNAME"); > + > + for (i = 0; i < count; i++) { > + xo_emit("{:lpwid/%6d} ", pl[i].pl_lwpid); > + switch (pl[i].pl_event) { > + case PL_EVENT_NONE: > + xo_emit("{eq:event/none}{d:event/%7s} ", "none"); > + break; > + case PL_EVENT_SIGNAL: > + xo_emit("{eq:event/signal}{d:event/%7s} ", "signal"); > + break; > + default: > + xo_emit("{eq:event/unknown}{d:event/%7s} ", "?"); > + break; > + } > + if ((pl[i].pl_flags & PL_FLAG_SI) != 0) { > + siginfo_t *si; > + > + si = &pl[i].pl_siginfo; > + xo_emit("{:signal_number/%5d} ", si->si_signo); > + xo_emit("{:code/%5d} ", si->si_code); > + xo_emit("{:signal_errno/%5d} ", si->si_errno); > + xo_emit("{:process_id/%6d} ", si->si_pid); > + xo_emit("{:user_id/%5d} ", si->si_uid); > + xo_emit("{[:/%d}{:address/%p}{]:} ", > + 2 * sizeof(void *) + 2, si->si_addr); > + } else { > + xo_emit("{:signal_number/%5s} ", "-"); > + xo_emit("{:code/%5s} ", "-"); > + xo_emit("{:signal_errno/%5s} ", "-"); > + xo_emit("{:process_id/%6s} ", "-"); > + xo_emit("{:user_id/%5s} ", "-"); > + xo_emit("{[:/%d}{:address/%s}{]:} ", > + 2 * sizeof(void *) + 2, "-"); > + } > + xo_emit("{:tdname/%s}\n", pl[i].pl_tdname); > + } > + > + procstat_freeptlwpinfo(prstat, pl); > +} > _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"