Author: jhb
Date: Thu Jul 14 23:20:05 2016
New Revision: 302859
URL: https://svnweb.freebsd.org/changeset/base/302859

Log:
  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.
  
  Reviewed by:  kib
  Differential Revision:        https://reviews.freebsd.org/D7116

Modified:
  head/sys/kern/imgact_elf.c
  head/usr.bin/gcore/elfcore.c

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c  Thu Jul 14 23:14:10 2016        (r302858)
+++ head/sys/kern/imgact_elf.c  Thu Jul 14 23:20:05 2016        (r302859)
@@ -1823,8 +1823,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) {
@@ -1833,13 +1837,43 @@ __elfN(note_prpsinfo)(void *arg, struct 
                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);
        }

Modified: head/usr.bin/gcore/elfcore.c
==============================================================================
--- head/usr.bin/gcore/elfcore.c        Thu Jul 14 23:14:10 2016        
(r302858)
+++ head/usr.bin/gcore/elfcore.c        Thu Jul 14 23:20:05 2016        
(r302859)
@@ -548,6 +548,7 @@ readmap(pid_t pid)
 static void *
 elf_note_prpsinfo(void *arg, size_t *sizep)
 {
+       char *cp, *end;
        pid_t pid;
        elfcore_prpsinfo_t *psinfo;
        struct kinfo_proc kip;
@@ -571,7 +572,20 @@ elf_note_prpsinfo(void *arg, size_t *siz
        if (kip.ki_pid != pid)
                err(1, "kern.proc.pid.%u", pid);
        strlcpy(psinfo->pr_fname, kip.ki_comm, sizeof(psinfo->pr_fname));
-       strlcpy(psinfo->pr_psargs, psinfo->pr_fname, sizeof(psinfo->pr_psargs));
+       name[2] = KERN_PROC_ARGS;
+       len = sizeof(psinfo->pr_psargs) - 1;
+       if (sysctl(name, 4, psinfo->pr_psargs, &len, NULL, 0) == 0 && len > 0) {
+               cp = psinfo->pr_psargs;
+               end = cp + len - 1;
+               for (;;) {
+                       cp = memchr(cp, '\0', end - cp);
+                       if (cp == NULL)
+                               break;
+                       *cp = ' ';
+               }
+       } else
+               strlcpy(psinfo->pr_psargs, kip.ki_comm,
+                   sizeof(psinfo->pr_psargs));
 
        *sizep = sizeof(*psinfo);
        return (psinfo);
_______________________________________________
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"

Reply via email to