From c6641bbcbc36abf157bfc90d6fdd86fbfd9d3382 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 6 Oct 2016 21:17:18 +0000 Subject: 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. --- sys/kern/imgact_elf.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'sys/kern') 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); } -- cgit v1.1