svn commit: r324932 - in stable/11: lib/libprocstat sys/kern sys/sys usr.bin/gcore usr.bin/procstat
Bryan Drewery
bdrewery at FreeBSD.org
Mon Oct 23 18:25:24 UTC 2017
Author: bdrewery
Date: Mon Oct 23 18:25:21 2017
New Revision: 324932
URL: https://svnweb.freebsd.org/changeset/base/324932
Log:
MFC r316286:
Add support for capturing 'struct ptrace_lwpinfo' for signals resulting in a
process dumping core in the corefile.
Direct stable changed: Padding added to struct thread and td_si added to end
with explicit bzeroing when forking/initializing a thread to preserve KBI.
Added:
stable/11/usr.bin/procstat/procstat_ptlwpinfo.c
- copied unchanged from r316286, head/usr.bin/procstat/procstat_ptlwpinfo.c
Modified:
stable/11/lib/libprocstat/Symbol.map
stable/11/lib/libprocstat/core.c
stable/11/lib/libprocstat/core.h
stable/11/lib/libprocstat/libprocstat.c
stable/11/lib/libprocstat/libprocstat.h
stable/11/sys/kern/imgact_elf.c
stable/11/sys/kern/kern_fork.c
stable/11/sys/kern/kern_kthread.c
stable/11/sys/kern/kern_sig.c
stable/11/sys/kern/kern_thr.c
stable/11/sys/kern/sys_process.c
stable/11/sys/sys/elf_common.h
stable/11/sys/sys/proc.h
stable/11/usr.bin/gcore/elfcore.c
stable/11/usr.bin/procstat/Makefile
stable/11/usr.bin/procstat/procstat.1
stable/11/usr.bin/procstat/procstat.c
stable/11/usr.bin/procstat/procstat.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/lib/libprocstat/Symbol.map
==============================================================================
--- stable/11/lib/libprocstat/Symbol.map Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/lib/libprocstat/Symbol.map Mon Oct 23 18:25:21 2017 (r324932)
@@ -36,3 +36,8 @@ FBSD_1.3 {
procstat_getvmmap;
procstat_open_core;
};
+
+FBSD_1.5 {
+ procstat_freeptlwpinfo;
+ procstat_getptlwpinfo;
+};
Modified: stable/11/lib/libprocstat/core.c
==============================================================================
--- stable/11/lib/libprocstat/core.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/lib/libprocstat/core.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2013 Mikolaj Golub <trociny at 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 *core, enum psc
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 *core, enum psc
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 *core, enum psc
}
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 *core, enum psc
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 *core, enum psc
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);
}
@@ -430,4 +420,58 @@ done:
*lenp = 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: stable/11/lib/libprocstat/core.h
==============================================================================
--- stable/11/lib/libprocstat/core.h Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/lib/libprocstat/core.h Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2013 Mikolaj Golub <trociny at 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: stable/11/lib/libprocstat/libprocstat.c
==============================================================================
--- stable/11/lib/libprocstat/libprocstat.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/lib/libprocstat/libprocstat.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2017 Dell EMC
* Copyright (c) 2009 Stanislav Sedov <stas at 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>
@@ -2467,6 +2469,48 @@ procstat_freeauxv(struct procstat *procstat __unused,
{
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 *
Modified: stable/11/lib/libprocstat/libprocstat.h
==============================================================================
--- stable/11/lib/libprocstat/libprocstat.h Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/lib/libprocstat/libprocstat.h Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2009 Stanislav Sedov <stas at 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 *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 *procstat, str
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: stable/11/sys/kern/imgact_elf.c
==============================================================================
--- stable/11/sys/kern/imgact_elf.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/imgact_elf.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -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>
@@ -1205,6 +1207,7 @@ static void __elfN(note_prpsinfo)(void *, struct sbuf
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 *);
@@ -1634,6 +1637,8 @@ __elfN(prepare_notes)(struct thread *td, struct note_i
__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);
@@ -1993,6 +1998,37 @@ __elfN(note_thrmisc)(void *arg, struct sbuf *sb, size_
sbuf_bcat(sb, &thrmisc, sizeof(thrmisc));
}
*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;
}
/*
Modified: stable/11/sys/kern/kern_fork.c
==============================================================================
--- stable/11/sys/kern/kern_fork.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/kern_fork.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -475,6 +475,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct
bzero(&td2->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
td2->td_sleeptimo = 0;
+ bzero(&td2->td_si, sizeof(td2->td_si));
bcopy(&td->td_startcopy, &td2->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
Modified: stable/11/sys/kern/kern_kthread.c
==============================================================================
--- stable/11/sys/kern/kern_kthread.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/kern_kthread.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -274,6 +274,7 @@ kthread_add(void (*func)(void *), void *arg, struct pr
bzero(&newtd->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
newtd->td_sleeptimo = 0;
+ bzero(&newtd->td_si, sizeof(newtd->td_si));
bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_sa = oldtd->td_sa;
Modified: stable/11/sys/kern/kern_sig.c
==============================================================================
--- stable/11/sys/kern/kern_sig.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/kern_sig.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -1243,6 +1243,19 @@ sys_sigwaitinfo(struct thread *td, struct sigwaitinfo_
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)
@@ -1351,8 +1364,10 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset,
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);
@@ -2805,6 +2820,7 @@ issignal(struct thread *td)
struct sigqueue *queue;
sigset_t sigpending;
int prop, sig, traced;
+ ksiginfo_t ksi;
p = td->td_proc;
ps = p->p_sigacts;
@@ -2860,14 +2876,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);
/*
@@ -3039,6 +3056,7 @@ postsig(int 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: stable/11/sys/kern/kern_thr.c
==============================================================================
--- stable/11/sys/kern/kern_thr.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/kern_thr.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -233,6 +233,7 @@ thread_create(struct thread *td, struct rtprio *rtp,
bzero(&newtd->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
newtd->td_sleeptimo = 0;
+ bzero(&newtd->td_si, sizeof(newtd->td_si));
bcopy(&td->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_sa = td->td_sa;
Modified: stable/11/sys/kern/sys_process.c
==============================================================================
--- stable/11/sys/kern/sys_process.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/kern/sys_process.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -1335,7 +1335,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, voi
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)) ||
@@ -1347,7 +1347,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, voi
#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: stable/11/sys/sys/elf_common.h
==============================================================================
--- stable/11/sys/sys/elf_common.h Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/sys/elf_common.h Mon Oct 23 18:25:21 2017 (r324932)
@@ -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: stable/11/sys/sys/proc.h
==============================================================================
--- stable/11/sys/sys/proc.h Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/sys/sys/proc.h Mon Oct 23 18:25:21 2017 (r324932)
@@ -275,7 +275,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. */
+ uint64_t padding3[14];
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. */
@@ -346,6 +346,7 @@ struct thread {
#define td_siglist td_sigqueue.sq_signals
struct syscall_args td_sa; /* (kx) Syscall parameters. Copied on
fork for child tracing. */
+ siginfo_t td_si; /* (c) For debugger or core file */
};
struct thread0_storage {
Modified: stable/11/usr.bin/gcore/elfcore.c
==============================================================================
--- stable/11/usr.bin/gcore/elfcore.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/usr.bin/gcore/elfcore.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -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 *, size_t *);
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
@@ -358,6 +360,7 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep
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
@@ -659,6 +662,24 @@ elf_note_thrmisc(void *arg, size_t *sizep)
*sizep = sizeof(*thrmisc);
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__)
Modified: stable/11/usr.bin/procstat/Makefile
==============================================================================
--- stable/11/usr.bin/procstat/Makefile Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/usr.bin/procstat/Makefile Mon Oct 23 18:25:21 2017 (r324932)
@@ -13,6 +13,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: stable/11/usr.bin/procstat/procstat.1
==============================================================================
--- stable/11/usr.bin/procstat/procstat.1 Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/usr.bin/procstat/procstat.1 Mon Oct 23 18:25:21 2017 (r324932)
@@ -38,7 +38,7 @@
.Op Fl M Ar core
.Op Fl N Ar system
.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
@@ -81,6 +81,8 @@ If the flag is repeated, function offsets as well as f
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: stable/11/usr.bin/procstat/procstat.c
==============================================================================
--- stable/11/usr.bin/procstat/procstat.c Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/usr.bin/procstat/procstat.c Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2007, 2011 Robert N. M. Watson
* Copyright (c) 2015 Allan Jude <allanjude at 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
@@ -85,6 +86,8 @@ procstat(struct procstat *prstat, struct kinfo_proc *k
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)
@@ -162,7 +165,7 @@ main(int argc, char *argv[])
argc = xo_parse_args(argc, argv);
xocontainer = "basic";
- while ((ch = getopt(argc, argv, "abCcefHhijklM:N:nrSstvw:x")) != -1) {
+ while ((ch = getopt(argc, argv, "abCcefHhijklLM:N:nrSstvw:x")) != -1) {
switch (ch) {
case 'C':
Cflag++;
@@ -224,6 +227,11 @@ main(int argc, char *argv[])
case 'l':
lflag++;
xocontainer = "rlimit";
+ break;
+
+ case 'L':
+ Lflag++;
+ xocontainer = "ptlwpinfo";
break;
case 'n':
Modified: stable/11/usr.bin/procstat/procstat.h
==============================================================================
--- stable/11/usr.bin/procstat/procstat.h Mon Oct 23 17:11:18 2017 (r324931)
+++ stable/11/usr.bin/procstat/procstat.h Mon Oct 23 18:25:21 2017 (r324932)
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2007 Robert N. M. Watson
* Copyright (c) 2015 Allan Jude <allanjude at 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 *prstat, struct kinf
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);
Copied: stable/11/usr.bin/procstat/procstat_ptlwpinfo.c (from r316286, head/usr.bin/procstat/procstat_ptlwpinfo.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/11/usr.bin/procstat/procstat_ptlwpinfo.c Mon Oct 23 18:25:21 2017 (r324932, copy of r316286, head/usr.bin/procstat/procstat_ptlwpinfo.c)
@@ -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);
+}
More information about the svn-src-stable
mailing list