Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/gpl3/gdb/dist/gdb Quick clean up the NetBSD support...



details:   https://anonhg.NetBSD.org/src/rev/1e197ce82c16
branches:  trunk
changeset: 451005:1e197ce82c16
user:      kamil <kamil%NetBSD.org@localhost>
date:      Fri May 03 07:05:28 2019 +0000

description:
Quick clean up the NetBSD support in GDB

Changes:

 - always perform polling on inferior_ptid, never -1
   -1 can cause catching fork/vfork events in random order
   polling on pid will guarantee to report events in expected order

 - assume availability of KERN_PROC_PATHNAME

 - drop dead code for KERN_PROC_AUXV (FreeBSD-specific sysctl)
   AUXV on NetBSD is handled with PIOD_READ_AUXV

 - drop unused nbsd_fetch_kinfo_proc

 - drop unneeded hacks for fork/vfork code

 - drop support for FreeBSD specific flags returned for PT_LWPINFO
   NetBSD uses PT_GET_SIGINFO / PT_GET_PROCESS_STATE for most pieces of
   information

 - port nbsd_thread_name to NetBSD

 - enable LWP and FORK events in nbsd_enable_proc_events

 - use NetBSD new batteries for distinguishing event type in to_wait
   map most events into GDB types
   breakpoint, single step, hw breakpoint/watchpoint ones are still not
   used with the full power here

 - add support for EXEC events

 - clean up

This change makes GDB functional with threaded code and it is good enough
to pass t_regress / threads test.

It's possible to execute and step processes with multiple threads, use
scheduler-lock, follow-fork etc features.


What does not work:

 - the LWP EXIT event and wait() are not synchronized and can deadlock
   this has been observed with exiting go applications

 - GDB VFORK code is still disabled and awaits kernel fixing

Short term goal is to correct LWP EXIT and follow up with VFORK fixes.

Long term goal is to rewrite NetBSD GDB support and write new support in
the remote process plugin (gdb-server) framework.

PR kern/53120
PR port-arm/51677
PR bin/54060
PR bin/49662
PR kern/52548

diffstat:

 external/gpl3/gdb/dist/gdb/infrun.c   |    4 +
 external/gpl3/gdb/dist/gdb/nbsd-nat.c |  473 ++++++++++++++-------------------
 2 files changed, 201 insertions(+), 276 deletions(-)

diffs (truncated from 670 to 300 lines):

diff -r 869be9ac66b3 -r 1e197ce82c16 external/gpl3/gdb/dist/gdb/infrun.c
--- a/external/gpl3/gdb/dist/gdb/infrun.c       Fri May 03 02:36:17 2019 +0000
+++ b/external/gpl3/gdb/dist/gdb/infrun.c       Fri May 03 07:05:28 2019 +0000
@@ -3874,7 +3874,11 @@
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   struct cleanup *ts_old_chain;
   int cmd_done = 0;
+#if defined(__NetBSD__)
+  ptid_t waiton_ptid = inferior_ptid;
+#else
   ptid_t waiton_ptid = minus_one_ptid;
+#endif
 
   memset (ecs, 0, sizeof (*ecs));
 
diff -r 869be9ac66b3 -r 1e197ce82c16 external/gpl3/gdb/dist/gdb/nbsd-nat.c
--- a/external/gpl3/gdb/dist/gdb/nbsd-nat.c     Fri May 03 02:36:17 2019 +0000
+++ b/external/gpl3/gdb/dist/gdb/nbsd-nat.c     Fri May 03 07:05:28 2019 +0000
@@ -45,7 +45,6 @@
   static char buf[PATH_MAX];
   char name[PATH_MAX];
 
-#ifdef KERN_PROC_PATHNAME
   size_t buflen;
   int mib[4];
 
@@ -56,7 +55,6 @@
   buflen = sizeof buf;
   if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
     return buf;
-#endif
 
   xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);
   len = readlink (name, buf, PATH_MAX - 1);
@@ -131,79 +129,6 @@
   return 0;
 }
 
-#ifdef KERN_PROC_AUXV
-static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops,
-                                                     enum target_object object,
-                                                     const char *annex,
-                                                     gdb_byte *readbuf,
-                                                     const gdb_byte *writebuf,
-                                                     ULONGEST offset,
-                                                     ULONGEST len,
-                                                     ULONGEST *xfered_len);
-
-/* Implement the "to_xfer_partial target_ops" method.  */
-
-static enum target_xfer_status
-nbsd_xfer_partial (struct target_ops *ops, enum target_object object,
-                  const char *annex, gdb_byte *readbuf,
-                  const gdb_byte *writebuf,
-                  ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
-{
-  pid_t pid = ptid_get_pid (inferior_ptid);
-
-  switch (object)
-    {
-    case TARGET_OBJECT_AUXV:
-      {
-       struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-       unsigned char *buf;
-       size_t buflen;
-       int mib[4];
-
-       if (writebuf != NULL)
-         return TARGET_XFER_E_IO;
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_PROC;
-       mib[2] = KERN_PROC_AUXV;
-       mib[3] = pid;
-       if (offset == 0)
-         {
-           buf = readbuf;
-           buflen = len;
-         }
-       else
-         {
-           buflen = offset + len;
-           buf = XCNEWVEC (unsigned char, buflen);
-           cleanup = make_cleanup (xfree, buf);
-         }
-       if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
-         {
-           if (offset != 0)
-             {
-               if (buflen > offset)
-                 {
-                   buflen -= offset;
-                   memcpy (readbuf, buf + offset, buflen);
-                 }
-               else
-                 buflen = 0;
-             }
-           do_cleanups (cleanup);
-           *xfered_len = buflen;
-           return (buflen == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
-         }
-       do_cleanups (cleanup);
-       return TARGET_XFER_E_IO;
-      }
-    default:
-      return super_xfer_partial (ops, object, annex, readbuf, writebuf, offset,
-                                len, xfered_len);
-    }
-}
-#endif
-
-#ifdef PT_LWPINFO
 static int debug_nbsd_lwp;
 
 static void (*super_resume) (struct target_ops *,
@@ -222,27 +147,6 @@
   fprintf_filtered (file, _("Debugging of NetBSD lwp module is %s.\n"), value);
 }
 
-#if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME)
-/* Fetch the external variant of the kernel's internal process
-   structure for the process PID into KP.  */
-
-static void
-nbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
-{
-  size_t len;
-  int mib[4];
-
-  len = sizeof *kp;
-  mib[0] = CTL_KERN;
-  mib[1] = KERN_PROC;
-  mib[2] = KERN_PROC_PID;
-  mib[3] = pid;
-  if (sysctl (mib, 4, kp, &len, NULL, 0) == -1)
-    perror_with_name (("sysctl"));
-}
-#endif
-
-
 /* Return true if PTID is still active in the inferior.  */
 
 static int
@@ -256,10 +160,6 @@
       if (ptrace (PT_LWPINFO, ptid_get_pid (ptid), (caddr_t) &pl, sizeof pl)
          == -1)
        return 0;
-#ifdef PL_FLAG_EXITED
-      if (pl.pl_flags & PL_FLAG_EXITED)
-       return 0;
-#endif
     }
 
   return 1;
@@ -286,77 +186,71 @@
   return normal_pid_to_str (ptid);
 }
 
-#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME
 /* Return the name assigned to a thread by an application.  Returns
    the string in a static buffer.  */
 
 static const char *
 nbsd_thread_name (struct target_ops *self, struct thread_info *thr)
 {
-  struct ptrace_lwpinfo pl;
-  struct kinfo_proc kp;
+  struct kinfo_lwp *kl;
   pid_t pid = ptid_get_pid (thr->ptid);
   lwpid_t lwp = ptid_get_lwp (thr->ptid);
-  static char buf[sizeof pl.pl_tdname + 1];
+  static char buf[KI_LNAMELEN];
+  int mib[5];
+  size_t i, nlwps;
+  size_t size;
+
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_LWP;
+  mib[2] = pid;
+  mib[3] = sizeof(struct kinfo_lwp);
+  mib[4] = 0;
+
+  if (sysctl(mib, 5, NULL, &size, NULL, 0) == -1 || size == 0)
+    perror_with_name (("sysctl"));
+
+  mib[4] = size / sizeof(size_t);
 
-  /* Note that ptrace_lwpinfo returns the process command in pl_tdname
-     if a name has not been set explicitly.  Return a NULL name in
-     that case.  */
-  nbsd_fetch_kinfo_proc (pid, &kp);
-  pl.pl_lwpid = lwp;
-  if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
-    perror_with_name (("ptrace"));
-  if (strcmp (kp.ki_comm, pl.pl_tdname) == 0)
-    return NULL;
-  xsnprintf (buf, sizeof buf, "%s", pl.pl_tdname);
+  kl = (struct kinfo_lwp *) xmalloc (size);
+  if (kl == NULL)
+    perror_with_name (("malloc"));
+
+  if (sysctl(mib, 5, kl, &size, NULL, 0) == -1 || size == 0)
+    perror_with_name (("sysctl"));
+
+  nlwps = size / sizeof(struct kinfo_lwp);
+  buf[0] = '\0';
+  for (i = 0; i < nlwps; i++) {
+    if (kl[i].l_lid == lwp) {
+      xsnprintf (buf, sizeof buf, "%s", kl[i].l_name);
+      break;
+    }
+  }
+  xfree(kl);
+
   return buf;
 }
-#endif
 
-/* Enable additional event reporting on new processes.
-
-   To catch fork events, PTRACE_FORK is set on every traced process
-   to enable stops on returns from fork or vfork.  Note that both the
-   parent and child will always stop, even if system call stops are
-   not enabled.
-
-   To catch LWP events, PTRACE_EVENTS is set on every traced process.
-   This enables stops on the birth for new LWPs (excluding the "main" LWP)
-   and the death of LWPs (excluding the last LWP in a process).  Note
-   that unlike fork events, the LWP that creates a new LWP does not
-   report an event.  */
+/* Enable additional event reporting on new processes. */
 
 static void
 nbsd_enable_proc_events (pid_t pid)
 {
-#ifdef PT_GET_EVENT_MASK
   int events;
 
   if (ptrace (PT_GET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
              sizeof (events)) == -1)
     perror_with_name (("ptrace"));
   events |= PTRACE_FORK;
-#ifdef PTRACE_LWP
-  events |= PTRACE_LWP;
+#ifdef notyet
+  events |= PTRACE_VFORK;
+  events |= PTRACE_VFORK_DONE;
 #endif
-#ifdef notyet
-#ifdef PTRACE_VFORK
-  events |= PTRACE_VFORK;
-#endif
-#endif
+  events |= PTRACE_LWP_CREATE;
+  events |= PTRACE_LWP_EXIT;
   if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
              sizeof (events)) == -1)
     perror_with_name (("ptrace"));
-#else
-#ifdef TDP_RFPPWAIT
-  if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3)0, 1) == -1)
-    perror_with_name (("ptrace"));
-#endif
-#ifdef PT_LWP_EVENTS
-  if (ptrace (PT_LWP_EVENTS, pid, (PTRACE_TYPE_ARG3)0, 1) == -1)
-    perror_with_name (("ptrace"));
-#endif
-#endif
 }
 
 /* Add threads for any new LWPs in a process.
@@ -371,7 +265,6 @@
   int val;
   struct ptrace_lwpinfo pl;
 
-//  gdb_assert (!in_thread_list (pid_to_ptid (pid)));
   pl.pl_lwpid = 0;
   while ((val = ptrace (PT_LWPINFO, pid, (void *)&pl, sizeof(pl))) != -1
     && pl.pl_lwpid != 0)
@@ -387,50 +280,11 @@
 static void
 nbsd_update_thread_list (struct target_ops *ops)
 {
-#ifdef PT_LWP_EVENTS
-  /* With support for thread events, threads are added/deleted from the
-     list as events are reported, so just try deleting exited threads.  */
-  delete_exited_threads ();
-#else
   prune_threads ();
 
   nbsd_add_threads (ptid_get_pid (inferior_ptid));
-#endif
 }
 
-#ifdef TDP_RFPPWAIT
-/*
-  To catch fork events, PT_FOLLOW_FORK is set on every traced process
-  to enable stops on returns from fork or vfork.  Note that both the
-  parent and child will always stop, even if system call stops are not
-  enabled.
-



Home | Main Index | Thread Index | Old Index