summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-10-06 21:17:18 +0000
committerjhb <jhb@FreeBSD.org>2016-10-06 21:17:18 +0000
commitc6641bbcbc36abf157bfc90d6fdd86fbfd9d3382 (patch)
treea4f92a68accde27ff97464b613b06a4e4d01bceb /sys/kern
parentae1958d197960436ece49a118519c2722ec64aaf (diff)
downloadFreeBSD-src-c6641bbcbc36abf157bfc90d6fdd86fbfd9d3382.zip
FreeBSD-src-c6641bbcbc36abf157bfc90d6fdd86fbfd9d3382.tar.gz
MFC 302859: Include command line arguments in core dump process info.
Fill in pr_psargs in the NT_PRSINFO ELF core dump note with command line arguments.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 1e237c2..40760bc 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1785,8 +1785,12 @@ typedef vm_offset_t elf_ps_strings_t;
static void
__elfN(note_prpsinfo)(void *arg, struct sbuf *sb, size_t *sizep)
{
+ struct sbuf sbarg;
+ size_t len;
+ char *cp, *end;
struct proc *p;
elf_prpsinfo_t *psinfo;
+ int error;
p = (struct proc *)arg;
if (sb != NULL) {
@@ -1795,13 +1799,43 @@ __elfN(note_prpsinfo)(void *arg, struct sbuf *sb, size_t *sizep)
psinfo->pr_version = PRPSINFO_VERSION;
psinfo->pr_psinfosz = sizeof(elf_prpsinfo_t);
strlcpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname));
- /*
- * XXX - We don't fill in the command line arguments properly
- * yet.
- */
- strlcpy(psinfo->pr_psargs, p->p_comm,
- sizeof(psinfo->pr_psargs));
-
+ PROC_LOCK(p);
+ if (p->p_args != NULL) {
+ len = sizeof(psinfo->pr_psargs) - 1;
+ if (len > p->p_args->ar_length)
+ len = p->p_args->ar_length;
+ memcpy(psinfo->pr_psargs, p->p_args->ar_args, len);
+ PROC_UNLOCK(p);
+ error = 0;
+ } else {
+ _PHOLD(p);
+ PROC_UNLOCK(p);
+ sbuf_new(&sbarg, psinfo->pr_psargs,
+ sizeof(psinfo->pr_psargs), SBUF_FIXEDLEN);
+ error = proc_getargv(curthread, p, &sbarg);
+ PRELE(p);
+ if (sbuf_finish(&sbarg) == 0)
+ len = sbuf_len(&sbarg) - 1;
+ else
+ len = sizeof(psinfo->pr_psargs) - 1;
+ sbuf_delete(&sbarg);
+ }
+ if (error || len == 0)
+ strlcpy(psinfo->pr_psargs, p->p_comm,
+ sizeof(psinfo->pr_psargs));
+ else {
+ KASSERT(len < sizeof(psinfo->pr_psargs),
+ ("len is too long: %zu vs %zu", len,
+ sizeof(psinfo->pr_psargs)));
+ cp = psinfo->pr_psargs;
+ end = cp + len - 1;
+ for (;;) {
+ cp = memchr(cp, '\0', end - cp);
+ if (cp == NULL)
+ break;
+ *cp = ' ';
+ }
+ }
sbuf_bcat(sb, psinfo, sizeof(*psinfo));
free(psinfo, M_TEMP);
}
OpenPOWER on IntegriCloud