Author: attilio
Date: Mon Dec 27 12:39:24 2010
New Revision: 216734
URL: http://svn.freebsd.org/changeset/base/216734

Log:
  MFC r215679:
  Add the ability for GDB to printout the thread name along with other thread
  specific informations.
  In order to achieve that, for both on-line debugging and core analysis,
  a new member to PT_LWPINFO ptrace(2) interface is added and a new
  ELF note (NT_THRMISC) as well.
  
  Sponsored by: Sandvine Incorporated

Modified:
  stable/8/contrib/binutils/bfd/elf-bfd.h
  stable/8/contrib/binutils/bfd/elf.c
  stable/8/contrib/binutils/binutils/readelf.c
  stable/8/contrib/binutils/include/elf/common.h
  stable/8/contrib/file/readelf.h
  stable/8/contrib/gdb/gdb/fbsd-proc.c
  stable/8/gnu/usr.bin/gdb/libgdb/fbsd-threads.c
  stable/8/sys/compat/freebsd32/freebsd32.h
  stable/8/sys/kern/imgact_elf.c
  stable/8/sys/kern/sys_process.c
  stable/8/sys/sys/elf_common.h
  stable/8/sys/sys/procfs.h
  stable/8/sys/sys/ptrace.h
  stable/8/usr.bin/gcore/elfcore.c
Directory Properties:
  stable/8/contrib/binutils/   (props changed)
  stable/8/contrib/file/   (props changed)
  stable/8/contrib/gdb/   (props changed)
  stable/8/gnu/usr.bin/gdb/   (props changed)
  stable/8/gnu/usr.bin/gdb/kgdb/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/usr.bin/gcore/   (props changed)

Modified: stable/8/contrib/binutils/bfd/elf-bfd.h
==============================================================================
--- stable/8/contrib/binutils/bfd/elf-bfd.h     Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/contrib/binutils/bfd/elf-bfd.h     Mon Dec 27 12:39:24 2010        
(r216734)
@@ -1673,6 +1673,8 @@ extern char * elfcore_write_pstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char *elfcore_write_prfpreg
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_thrmisc
+  (bfd *, char *, int *, const char *, int);
 extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_lwpstatus

Modified: stable/8/contrib/binutils/bfd/elf.c
==============================================================================
--- stable/8/contrib/binutils/bfd/elf.c Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/contrib/binutils/bfd/elf.c Mon Dec 27 12:39:24 2010        
(r216734)
@@ -6316,6 +6316,12 @@ _bfd_elf_rel_vtable_reloc_fn
 
 #ifdef HAVE_SYS_PROCFS_H
 # include <sys/procfs.h>
+
+/* Define HAVE_THRMISC_T for consistency with other similar GNU-type stubs. */
+#undef HAVE_THRMISC_T
+#if defined (THRMISC_VERSION)
+#define        HAVE_THRMISC_T  1
+#endif
 #endif
 
 /* FIXME: this is kinda wrong, but it's what gdb wants.  */
@@ -6497,6 +6503,16 @@ elfcore_grok_prxfpreg (bfd *abfd, Elf_In
   return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
 }
 
+#if defined (HAVE_THRMISC_T)
+
+static bfd_boolean
+elfcore_grok_thrmisc (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".tname", note);
+}
+
+#endif /* defined (HAVE_THRMISC_T) */
+
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)                /* Sparc64 cross Sparc32 */
@@ -6863,6 +6879,12 @@ elfcore_grok_note (bfd *abfd, Elf_Intern
 
        return TRUE;
       }
+
+#if defined (HAVE_THRMISC_T)
+    case NT_THRMISC:
+      return elfcore_grok_thrmisc (abfd, note);
+#endif
+
     }
 }
 
@@ -7245,6 +7267,22 @@ elfcore_write_prfpreg (bfd *abfd,
 }
 
 char *
+elfcore_write_thrmisc (bfd *abfd,
+                      char *buf,
+                      int *bufsiz,
+                      const char *tname,
+                      int size)
+{
+#if defined (HAVE_THRMISC_T)
+  char *note_name = "CORE";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_THRMISC, tname, size);
+#else
+  return buf;
+#endif
+}
+
+char *
 elfcore_write_prxfpreg (bfd *abfd,
                        char *buf,
                        int *bufsiz,

Modified: stable/8/contrib/binutils/binutils/readelf.c
==============================================================================
--- stable/8/contrib/binutils/binutils/readelf.c        Mon Dec 27 12:06:38 
2010        (r216733)
+++ stable/8/contrib/binutils/binutils/readelf.c        Mon Dec 27 12:39:24 
2010        (r216734)
@@ -9908,6 +9908,7 @@ get_note_type (unsigned e_type)
     case NT_PSTATUS:   return _("NT_PSTATUS (pstatus structure)");
     case NT_FPREGS:    return _("NT_FPREGS (floating point registers)");
     case NT_PSINFO:    return _("NT_PSINFO (psinfo structure)");
+    case NT_THRMISC:   return _("NT_THRMISC (thrmisc structure)");
     case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
     case NT_LWPSINFO:  return _("NT_LWPSINFO (lwpsinfo_t structure)");
     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus 
structure)");

Modified: stable/8/contrib/binutils/include/elf/common.h
==============================================================================
--- stable/8/contrib/binutils/include/elf/common.h      Mon Dec 27 12:06:38 
2010        (r216733)
+++ stable/8/contrib/binutils/include/elf/common.h      Mon Dec 27 12:39:24 
2010        (r216734)
@@ -366,6 +366,7 @@
 #define NT_PRPSINFO    3               /* Contains copy of prpsinfo struct */
 #define NT_TASKSTRUCT  4               /* Contains copy of task struct */
 #define NT_AUXV                6               /* Contains copy of 
Elfxx_auxv_t */
+#define NT_THRMISC     7               /* Contains copy of thrmisc struct */
 #define NT_PRXFPREG    0x46e62b7f      /* Contains a user_xfpregs_struct; */
                                        /*   note name must be "LINUX".  */
 

Modified: stable/8/contrib/file/readelf.h
==============================================================================
--- stable/8/contrib/file/readelf.h     Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/contrib/file/readelf.h     Mon Dec 27 12:39:24 2010        
(r216734)
@@ -224,6 +224,7 @@ typedef struct {
 #define NT_TASKSTRUCT  4
 #define        NT_PLATFORM     5
 #define        NT_AUXV         6
+#define        NT_THRMISC      7
 
 /* Note types used in executables */
 /* NetBSD executables (name = "NetBSD") */

Modified: stable/8/contrib/gdb/gdb/fbsd-proc.c
==============================================================================
--- stable/8/contrib/gdb/gdb/fbsd-proc.c        Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/contrib/gdb/gdb/fbsd-proc.c        Mon Dec 27 12:39:24 2010        
(r216734)
@@ -124,6 +124,7 @@ fbsd_make_corefile_notes (bfd *obfd, int
   fpregset_t fpregs;
   char *note_data = NULL;
   Elf_Internal_Ehdr *i_ehdrp;
+  char fakename;
 
   /* Put a "FreeBSD" label in the ELF header.  */
   i_ehdrp = elf_elfheader (obfd);
@@ -138,6 +139,10 @@ fbsd_make_corefile_notes (bfd *obfd, int
   note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
                                     &fpregs, sizeof (fpregs));
 
+  fakename = '\0';
+  note_data = elfcore_write_thrmisc (obfd, note_data, note_size,
+                                    &fakename, sizeof (fakename));
+
   if (get_exec_file (0))
     {
       char *fname = strrchr (get_exec_file (0), '/') + 1;

Modified: stable/8/gnu/usr.bin/gdb/libgdb/fbsd-threads.c
==============================================================================
--- stable/8/gnu/usr.bin/gdb/libgdb/fbsd-threads.c      Mon Dec 27 12:06:38 
2010        (r216733)
+++ stable/8/gnu/usr.bin/gdb/libgdb/fbsd-threads.c      Mon Dec 27 12:39:24 
2010        (r216734)
@@ -426,6 +426,46 @@ fbsd_thread_deactivate (void)
   init_thread_list ();
 }
 
+static char * 
+fbsd_thread_get_name (lwpid_t lwpid)
+{
+  static char last_thr_name[MAXCOMLEN + 1];
+  char section_name[32];
+  struct ptrace_lwpinfo lwpinfo;
+  bfd_size_type size;
+  struct bfd_section *section;
+
+  if (target_has_execution)
+    {
+      if (ptrace (PT_LWPINFO, lwpid, (caddr_t)&lwpinfo, sizeof (lwpinfo)) == 
-1)
+        goto fail;
+      strncpy (last_thr_name, lwpinfo.pl_tdname, sizeof (last_thr_name) - 1);
+    }
+  else
+    {
+      snprintf (section_name, sizeof (section_name), ".tname/%u", lwpid);
+      section = bfd_get_section_by_name (core_bfd, section_name);
+      if (! section)
+        goto fail;
+
+      /* Section size fix-up. */
+      size = bfd_section_size (core_bfd, section);
+      if (size > sizeof (last_thr_name))
+        size = sizeof (last_thr_name);
+
+      if (! bfd_get_section_contents (core_bfd, section, last_thr_name,
+              (file_ptr)0, size))
+        goto fail;
+      if (last_thr_name[0] == '\0')
+        goto fail;
+    }
+    last_thr_name[sizeof (last_thr_name) - 1] = '\0';
+    return last_thr_name;
+fail:
+     strcpy (last_thr_name, "<unknown>");
+     return last_thr_name;
+}
+
 static void
 fbsd_thread_new_objfile (struct objfile *objfile)
 {
@@ -1158,7 +1198,7 @@ fbsd_thread_find_new_threads (void)
 static char *
 fbsd_thread_pid_to_str (ptid_t ptid)
 {
-  static char buf[64];
+  static char buf[64 + MAXCOMLEN];
 
   if (IS_THREAD (ptid))
     {
@@ -1178,8 +1218,9 @@ fbsd_thread_pid_to_str (ptid_t ptid)
 
       if (ti.ti_lid != 0)
         {
-          snprintf (buf, sizeof (buf), "Thread %llx (LWP %d)",
-                    (unsigned long long)th.th_thread, ti.ti_lid);
+          snprintf (buf, sizeof (buf), "Thread %llx (LWP %d/%s)",
+                    (unsigned long long)th.th_thread, ti.ti_lid,
+                    fbsd_thread_get_name (ti.ti_lid));
         }
       else
         {

Modified: stable/8/sys/compat/freebsd32/freebsd32.h
==============================================================================
--- stable/8/sys/compat/freebsd32/freebsd32.h   Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/sys/compat/freebsd32/freebsd32.h   Mon Dec 27 12:39:24 2010        
(r216734)
@@ -240,6 +240,11 @@ struct prpsinfo32 {
         char    pr_psargs[PRARGSZ+1];
 };
 
+struct thrmisc32 {
+        char    pr_tname[MAXCOMLEN+1];
+        u_int   _pad;
+};
+
 struct mq_attr32 {
        int     mq_flags;
        int     mq_maxmsg;

Modified: stable/8/sys/kern/imgact_elf.c
==============================================================================
--- stable/8/sys/kern/imgact_elf.c      Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/sys/kern/imgact_elf.c      Mon Dec 27 12:39:24 2010        
(r216734)
@@ -1213,12 +1213,14 @@ typedef struct prpsinfo32 elf_prpsinfo_t
 typedef struct fpreg32 elf_prfpregset_t;
 typedef struct fpreg32 elf_fpregset_t;
 typedef struct reg32 elf_gregset_t;
+typedef struct thrmisc32 elf_thrmisc_t;
 #else
 typedef prstatus_t elf_prstatus_t;
 typedef prpsinfo_t elf_prpsinfo_t;
 typedef prfpregset_t elf_prfpregset_t;
 typedef prfpregset_t elf_fpregset_t;
 typedef gregset_t elf_gregset_t;
+typedef thrmisc_t elf_thrmisc_t;
 #endif
 
 static void
@@ -1228,10 +1230,12 @@ __elfN(puthdr)(struct thread *td, void *
                elf_prstatus_t status;
                elf_prfpregset_t fpregset;
                elf_prpsinfo_t psinfo;
+               elf_thrmisc_t thrmisc;
        } *tempdata;
        elf_prstatus_t *status;
        elf_prfpregset_t *fpregset;
        elf_prpsinfo_t *psinfo;
+       elf_thrmisc_t *thrmisc;
        struct proc *p;
        struct thread *thr;
        size_t ehoff, noteoff, notesz, phoff;
@@ -1254,11 +1258,13 @@ __elfN(puthdr)(struct thread *td, void *
                status = &tempdata->status;
                fpregset = &tempdata->fpregset;
                psinfo = &tempdata->psinfo;
+               thrmisc = &tempdata->thrmisc;
        } else {
                tempdata = NULL;
                status = NULL;
                fpregset = NULL;
                psinfo = NULL;
+               thrmisc = NULL;
        }
 
        if (dst != NULL) {
@@ -1298,11 +1304,15 @@ __elfN(puthdr)(struct thread *td, void *
                        fill_regs(thr, &status->pr_reg);
                        fill_fpregs(thr, fpregset);
 #endif
+                       memset(&thrmisc->_pad, 0, sizeof (thrmisc->_pad));
+                       strcpy(thrmisc->pr_tname, thr->td_name);
                }
                __elfN(putnote)(dst, off, "FreeBSD", NT_PRSTATUS, status,
                    sizeof *status);
                __elfN(putnote)(dst, off, "FreeBSD", NT_FPREGSET, fpregset,
                    sizeof *fpregset);
+               __elfN(putnote)(dst, off, "FreeBSD", NT_THRMISC, thrmisc,
+                   sizeof *thrmisc);
                /*
                 * Allow for MD specific notes, as well as any MD
                 * specific preparations for writing MI notes.

Modified: stable/8/sys/kern/sys_process.c
==============================================================================
--- stable/8/sys/kern/sys_process.c     Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/sys/kern/sys_process.c     Mon Dec 27 12:39:24 2010        
(r216734)
@@ -92,6 +92,7 @@ struct ptrace_lwpinfo32 {
        sigset_t        pl_sigmask;     /* LWP signal mask */
        sigset_t        pl_siglist;     /* LWP pending signal */
        struct siginfo32 pl_siginfo;    /* siginfo for signal */
+       char    pl_tdname[MAXCOMLEN + 1];       /* LWP name. */
 };
 
 #endif
@@ -517,6 +518,7 @@ ptrace_lwpinfo_to32(const struct ptrace_
        pl32->pl_sigmask = pl->pl_sigmask;
        pl32->pl_siglist = pl->pl_siglist;
        siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
+       strcpy(pl32->pl_tdname, pl->pl_tdname);
 }
 #endif /* COMPAT_FREEBSD32 */
 
@@ -1172,6 +1174,7 @@ kern_ptrace(struct thread *td, int req, 
                        pl->pl_flags |= PL_FLAG_EXEC;
                pl->pl_sigmask = td2->td_sigmask;
                pl->pl_siglist = td2->td_siglist;
+               strcpy(pl->pl_tdname, td2->td_name);
 #ifdef COMPAT_FREEBSD32
                if (wrap32)
                        ptrace_lwpinfo_to32(pl, pl32);

Modified: stable/8/sys/sys/elf_common.h
==============================================================================
--- stable/8/sys/sys/elf_common.h       Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/sys/sys/elf_common.h       Mon Dec 27 12:39:24 2010        
(r216734)
@@ -480,6 +480,7 @@ typedef struct {
 #define        NT_PRSTATUS     1       /* Process status. */
 #define        NT_FPREGSET     2       /* Floating point registers. */
 #define        NT_PRPSINFO     3       /* Process state info. */
+#define        NT_THRMISC      7       /* Thread miscellaneous info. */
 
 /* Symbol Binding - ELFNN_ST_BIND - st_info */
 #define        STB_LOCAL       0       /* Local symbol */

Modified: stable/8/sys/sys/procfs.h
==============================================================================
--- stable/8/sys/sys/procfs.h   Mon Dec 27 12:06:38 2010        (r216733)
+++ stable/8/sys/sys/procfs.h   Mon Dec 27 12:39:24 2010        (r216734)
@@ -80,6 +80,13 @@ typedef struct prpsinfo {
     char       pr_psargs[PRARGSZ+1];   /* Arguments, null terminated (1) */
 } prpsinfo_t;
 
+#define THRMISC_VERSION                1       /* Current version of thrmisc_t 
*/
+
+typedef struct thrmisc {
+    char       pr_tname[MAXCOMLEN+1];  /* Thread name, null terminated (1) */
+    u_int      _pad;                   /* Convenience pad, 0-filled (1) */
+} thrmisc_t;
+
 typedef uint64_t psaddr_t;     /* An address in the target process. */
 
 #endif /* _SYS_PROCFS_H_ */

Modified: stable/8/sys/sys/ptrace.h
==============================================================================
--- stable/8/sys/sys/ptrace.h   Mon Dec 27 12:06:38 2010        (r216733)
+++ stable/8/sys/sys/ptrace.h   Mon Dec 27 12:39:24 2010        (r216734)
@@ -34,6 +34,7 @@
 #define        _SYS_PTRACE_H_
 
 #include <sys/signal.h>
+#include <sys/param.h>
 #include <machine/reg.h>
 
 #define        PT_TRACE_ME     0       /* child declares it's being traced */
@@ -106,6 +107,7 @@ struct ptrace_lwpinfo {
        sigset_t        pl_sigmask;     /* LWP signal mask */
        sigset_t        pl_siglist;     /* LWP pending signal */
        struct __siginfo pl_siginfo;    /* siginfo for signal */
+       char            pl_tdname[MAXCOMLEN + 1]; /* LWP name */
 };
 
 /* Argument structure for PT_VM_ENTRY. */

Modified: stable/8/usr.bin/gcore/elfcore.c
==============================================================================
--- stable/8/usr.bin/gcore/elfcore.c    Mon Dec 27 12:06:38 2010        
(r216733)
+++ stable/8/usr.bin/gcore/elfcore.c    Mon Dec 27 12:39:24 2010        
(r216734)
@@ -284,10 +284,12 @@ elf_getstatus(pid_t pid, prpsinfo_t *psi
 static void
 elf_puthdr(pid_t pid, vm_map_entry_t map, void *dst, size_t *off, int numsegs)
 {
+       struct ptrace_lwpinfo lwpinfo;
        struct {
                prstatus_t status;
                prfpregset_t fpregset;
                prpsinfo_t psinfo;
+               thrmisc_t thrmisc;
        } *tempdata;
        size_t ehoff;
        size_t phoff;
@@ -300,6 +302,7 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
        prstatus_t *status;
        prfpregset_t *fpregset;
        prpsinfo_t *psinfo;
+       thrmisc_t *thrmisc;
 
        ehoff = *off;
        *off += sizeof(Elf_Ehdr);
@@ -315,11 +318,13 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
                status = &tempdata->status;
                fpregset = &tempdata->fpregset;
                psinfo = &tempdata->psinfo;
+               thrmisc = &tempdata->thrmisc;
        } else {
                tempdata = NULL;
                status = NULL;
                fpregset = NULL;
                psinfo = NULL;
+               thrmisc = NULL;
        }
 
        errno = 0;
@@ -356,11 +361,17 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
 
                        ptrace(PT_GETREGS, tids[i], (void *)&status->pr_reg, 0);
                        ptrace(PT_GETFPREGS, tids[i], (void *)fpregset, 0);
+                       ptrace(PT_LWPINFO, tids[i], (void *)&lwpinfo,
+                           sizeof(lwpinfo));
+                       memset(&thrmisc->_pad, 0, sizeof(thrmisc->_pad));
+                       strcpy(thrmisc->pr_tname, lwpinfo.pl_tdname);
                }
                elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status,
                    sizeof *status);
                elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset,
                    sizeof *fpregset);
+               elf_putnote(dst, off, "FreeBSD", NT_THRMISC, thrmisc,
+                   sizeof *thrmisc);
        }
 
        notesz = *off - noteoff;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to