* source.c (openp): Skip $cdir in PATH.
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index 48ea1bc46c81b40c72f83eb5109f4f66e6f2222b..e7e001bc4d5d445a0dbc545f2d83ea5b6da2d9e2 100644 (file)
@@ -1105,25 +1105,6 @@ status_to_str (int status)
   return buf;
 }
 
-/* Initialize the list of LWPs.  Note that this module, contrary to
-   what GDB's generic threads layer does for its thread list,
-   re-initializes the LWP lists whenever we mourn or detach (which
-   doesn't involve mourning) the inferior.  */
-
-static void
-init_lwp_list (void)
-{
-  struct lwp_info *lp, *lpnext;
-
-  for (lp = lwp_list; lp; lp = lpnext)
-    {
-      lpnext = lp->next;
-      xfree (lp);
-    }
-
-  lwp_list = NULL;
-}
-
 /* Remove all LWPs belong to PID from the lwp list.  */
 
 static void
@@ -1184,6 +1165,7 @@ add_lwp (ptid_t ptid)
   lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
 
   lp->ptid = ptid;
+  lp->core = -1;
 
   lp->next = lwp_list;
   lwp_list = lp;
@@ -1239,33 +1221,6 @@ find_lwp_pid (ptid_t ptid)
   return NULL;
 }
 
-/* Returns true if PTID matches filter FILTER.  FILTER can be the wild
-   card MINUS_ONE_PTID (all ptid match it); can be a ptid representing
-   a process (ptid_is_pid returns true), in which case, all lwps of
-   that give process match, lwps of other process do not; or, it can
-   represent a specific thread, in which case, only that thread will
-   match true.  PTID must represent an LWP, it can never be a wild
-   card.  */
-
-static int
-ptid_match (ptid_t ptid, ptid_t filter)
-{
-  /* Since both parameters have the same type, prevent easy mistakes
-     from happening.  */
-  gdb_assert (!ptid_equal (ptid, minus_one_ptid)
-             && !ptid_equal (ptid, null_ptid));
-
-  if (ptid_equal (filter, minus_one_ptid))
-    return 1;
-  if (ptid_is_pid (filter)
-      && ptid_get_pid (ptid) == ptid_get_pid (filter))
-    return 1;
-  else if (ptid_equal (ptid, filter))
-    return 1;
-
-  return 0;
-}
-
 /* Call CALLBACK with its second argument set to DATA for every LWP in
    the list.  If CALLBACK returns 1 for a particular LWP, return a
    pointer to the structure describing that LWP immediately.
@@ -1828,10 +1783,11 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty)
         pass it along with PTRACE_DETACH.  */
       args = alloca (8);
       sprintf (args, "%d", (int) WSTOPSIG (status));
-      fprintf_unfiltered (gdb_stdlog,
-                         "LND: Sending signal %s to %s\n",
-                         args,
-                         target_pid_to_str (main_lwp->ptid));
+      if (debug_linux_nat)
+       fprintf_unfiltered (gdb_stdlog,
+                           "LND: Sending signal %s to %s\n",
+                           args,
+                           target_pid_to_str (main_lwp->ptid));
     }
 
   delete_lwp (main_lwp->ptid);
@@ -1930,14 +1886,8 @@ linux_nat_resume (struct target_ops *ops,
   resume_many = (ptid_equal (minus_one_ptid, ptid)
                 || ptid_is_pid (ptid));
 
-  if (!non_stop)
-    {
-      /* Mark the lwps we're resuming as resumed.  */
-      iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
-      iterate_over_lwps (ptid, resume_set_callback, NULL);
-    }
-  else
-    iterate_over_lwps (minus_one_ptid, resume_set_callback, NULL);
+  /* Mark the lwps we're resuming as resumed.  */
+  iterate_over_lwps (ptid, resume_set_callback, NULL);
 
   /* See if it's the current inferior that should be handled
      specially.  */
@@ -3280,8 +3230,20 @@ retry:
   lp = NULL;
   status = 0;
 
-  /* Make sure there is at least one LWP that has been resumed.  */
-  gdb_assert (iterate_over_lwps (ptid, resumed_callback, NULL));
+  /* Make sure that of those LWPs we want to get an event from, there
+     is at least one LWP that has been resumed.  If there's none, just
+     bail out.  The core may just be flushing asynchronously all
+     events.  */
+  if (iterate_over_lwps (ptid, resumed_callback, NULL) == NULL)
+    {
+      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
+      if (debug_linux_nat_async)
+       fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
+
+      restore_child_signals_mask (&prev_mask);
+      return minus_one_ptid;
+    }
 
   /* First check if there is a LWP with a wait status pending.  */
   if (pid == -1)
@@ -3412,6 +3374,8 @@ retry:
              && ptid_is_pid (ptid)
              && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
            {
+             gdb_assert (lp->resumed);
+
              if (debug_linux_nat)
                fprintf (stderr, "LWP %ld got an event %06x, leaving pending.\n",
                         ptid_get_lwp (lp->ptid), status);
@@ -3420,12 +3384,30 @@ retry:
                {
                  if (WSTOPSIG (lp->status) != SIGSTOP)
                    {
-                     stop_callback (lp, NULL);
-
-                     /* Resume in order to collect the sigstop.  */
-                     ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
-
-                     stop_wait_callback (lp, NULL);
+                     /* Cancel breakpoint hits.  The breakpoint may
+                        be removed before we fetch events from this
+                        process to report to the core.  It is best
+                        not to assume the moribund breakpoints
+                        heuristic always handles these cases --- it
+                        could be too many events go through to the
+                        core before this one is handled.  All-stop
+                        always cancels breakpoint hits in all
+                        threads.  */
+                     if (non_stop
+                         && lp->waitstatus.kind == TARGET_WAITKIND_IGNORE
+                         && WSTOPSIG (lp->status) == SIGTRAP
+                         && cancel_breakpoint (lp))
+                       {
+                         /* Throw away the SIGTRAP.  */
+                         lp->status = 0;
+
+                         if (debug_linux_nat)
+                           fprintf (stderr,
+                                    "LLW: LWP %ld hit a breakpoint while waiting "
+                                    "for another process; cancelled it\n",
+                                    ptid_get_lwp (lp->ptid));
+                       }
+                     lp->stopped = 1;
                    }
                  else
                    {
@@ -3615,12 +3597,19 @@ retry:
         starvation.  */
       if (pid == -1)
        select_event_lwp (ptid, &lp, &status);
-    }
 
-  /* Now that we've selected our final event LWP, cancel any
-     breakpoints in other LWPs that have hit a GDB breakpoint.  See
-     the comment in cancel_breakpoints_callback to find out why.  */
-  iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
+      /* Now that we've selected our final event LWP, cancel any
+        breakpoints in other LWPs that have hit a GDB breakpoint.
+        See the comment in cancel_breakpoints_callback to find out
+        why.  */
+      iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
+
+      /* In all-stop, from the core's perspective, all LWPs are now
+        stopped until a new resume action is sent over.  */
+      iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
+    }
+  else
+    lp->resumed = 0;
 
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
     {
@@ -3642,9 +3631,51 @@ retry:
     fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
 
   restore_child_signals_mask (&prev_mask);
+  lp->core = linux_nat_core_of_thread_1 (lp->ptid);
   return lp->ptid;
 }
 
+/* Resume LWPs that are currently stopped without any pending status
+   to report, but are resumed from the core's perspective.  */
+
+static int
+resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
+{
+  ptid_t *wait_ptid_p = data;
+
+  if (lp->stopped
+      && lp->resumed
+      && lp->status == 0
+      && lp->waitstatus.kind == TARGET_WAITKIND_IGNORE)
+    {
+      gdb_assert (is_executing (lp->ptid));
+
+      /* Don't bother if there's a breakpoint at PC that we'd hit
+        immediately, and we're not waiting for this LWP.  */
+      if (!ptid_match (lp->ptid, *wait_ptid_p))
+       {
+         struct regcache *regcache = get_thread_regcache (lp->ptid);
+         CORE_ADDR pc = regcache_read_pc (regcache);
+
+         if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+           return 0;
+       }
+
+      if (debug_linux_nat)
+       fprintf_unfiltered (gdb_stdlog,
+                           "RSRL: resuming stopped-resumed LWP %s\n",
+                           target_pid_to_str (lp->ptid));
+
+      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+                           lp->step, TARGET_SIGNAL_0);
+      lp->stopped = 0;
+      memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+      lp->stopped_by_watchpoint = 0;
+    }
+
+  return 0;
+}
+
 static ptid_t
 linux_nat_wait (struct target_ops *ops,
                ptid_t ptid, struct target_waitstatus *ourstatus,
@@ -3659,6 +3690,16 @@ linux_nat_wait (struct target_ops *ops,
   if (target_can_async_p ())
     async_file_flush ();
 
+  /* Resume LWPs that are currently stopped without any pending status
+     to report, but are resumed from the core's perspective.  LWPs get
+     in this state if we find them stopping at a time we're not
+     interested in reporting the event (target_wait on a
+     specific_process, for example, see linux_nat_wait_1), and
+     meanwhile the event became uninteresting.  Don't bother resuming
+     LWPs we're not going to wait for if they'd stop immediately.  */
+  if (non_stop)
+    iterate_over_lwps (minus_one_ptid, resume_stopped_resumed_lwps, &ptid);
+
   event_ptid = linux_nat_wait_1 (ops, ptid, ourstatus, target_options);
 
   /* If we requested any event, and something came out, assume there
@@ -4045,8 +4086,8 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
       if (info_verbose)
        {
          fprintf_filtered (gdb_stdout,
-                           "Save segment, %lld bytes at %s (%c%c%c)",
-                           size, paddress (target_gdbarch, addr),
+                           "Save segment, %s bytes at %s (%c%c%c)",
+                           plongest (size), paddress (target_gdbarch, addr),
                            read ? 'r' : ' ',
                            write ? 'w' : ' ', exec ? 'x' : ' ');
          if (filename[0])
@@ -5007,7 +5048,7 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
   LONGEST xfer;
 
   if (object == TARGET_OBJECT_AUXV)
-    return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
+    return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
                             offset, len);
 
   if (object == TARGET_OBJECT_OSDATA)
@@ -5423,6 +5464,75 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid)
   return inf->aspace;
 }
 
+int
+linux_nat_core_of_thread_1 (ptid_t ptid)
+{
+  struct cleanup *back_to;
+  char *filename;
+  FILE *f;
+  char *content = NULL;
+  char *p;
+  char *ts = 0;
+  int content_read = 0;
+  int i;
+  int core;
+
+  filename = xstrprintf ("/proc/%d/task/%ld/stat",
+                        GET_PID (ptid), GET_LWP (ptid));
+  back_to = make_cleanup (xfree, filename);
+
+  f = fopen (filename, "r");
+  if (!f)
+    {
+      do_cleanups (back_to);
+      return -1;
+    }
+
+  make_cleanup_fclose (f);
+
+  for (;;)
+    {
+      int n;
+      content = xrealloc (content, content_read + 1024);
+      n = fread (content + content_read, 1, 1024, f);
+      content_read += n;
+      if (n < 1024)
+       {
+         content[content_read] = '\0';
+         break;
+       }
+    }
+
+  make_cleanup (xfree, content);
+
+  p = strchr (content, '(');
+  p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */
+
+  /* If the first field after program name has index 0, then core number is
+     the field with index 36.  There's no constant for that anywhere.  */
+  p = strtok_r (p, " ", &ts);
+  for (i = 0; i != 36; ++i)
+    p = strtok_r (NULL, " ", &ts);
+
+  if (sscanf (p, "%d", &core) == 0)
+    core = -1;
+
+  do_cleanups (back_to);
+
+  return core;
+}
+
+/* Return the cached value of the processor core for thread PTID.  */
+
+int
+linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
+{
+  struct lwp_info *info = find_lwp_pid (ptid);
+  if (info)
+    return info->core;
+  return -1;
+}
+
 void
 linux_nat_add_target (struct target_ops *t)
 {
@@ -5463,6 +5573,8 @@ linux_nat_add_target (struct target_ops *t)
 
   t->to_supports_multi_process = linux_nat_supports_multi_process;
 
+  t->to_core_of_thread = linux_nat_core_of_thread;
+
   /* We don't change the stratum; this target will sit at
      process_stratum and thread_db will set at thread_stratum.  This
      is a little strange, since this is a multi-threaded-capable
This page took 0.027918 seconds and 4 git commands to generate.