[Ada/ravenscar] error during "continue" after task/thread switch
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index a47c49609b964df35236c3d8613de4ace8ce4772..5a4abb1834a744fa1c8b0066bb0854aa15986924 100644 (file)
@@ -1497,12 +1497,10 @@ detach_callback (struct lwp_info *lp, void *data)
 }
 
 static void
-linux_nat_detach (struct target_ops *ops, const char *args, int from_tty)
+linux_nat_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
-  int pid;
   struct lwp_info *main_lwp;
-
-  pid = ptid_get_pid (inferior_ptid);
+  int pid = inf->pid;
 
   /* Don't unregister from the event loop, as there may be other
      inferiors running. */
@@ -1517,7 +1515,7 @@ linux_nat_detach (struct target_ops *ops, const char *args, int from_tty)
   iterate_over_lwps (pid_to_ptid (pid), detach_callback, NULL);
 
   /* Only the initial process should be left right now.  */
-  gdb_assert (num_lwps (ptid_get_pid (inferior_ptid)) == 1);
+  gdb_assert (num_lwps (pid) == 1);
 
   main_lwp = find_lwp_pid (pid_to_ptid (pid));
 
@@ -1527,25 +1525,18 @@ linux_nat_detach (struct target_ops *ops, const char *args, int from_tty)
         from, but there are other viable forks to debug.  Detach from
         the current fork, and context-switch to the first
         available.  */
-      linux_fork_detach (args, from_tty);
+      linux_fork_detach (from_tty);
     }
   else
     {
-      int signo;
-
       target_announce_detach (from_tty);
 
-      /* Pass on any pending signal for the last LWP, unless the user
-        requested detaching with a different signal (most likely 0,
-        meaning, discard the signal).  */
-      if (args != NULL)
-       signo = atoi (args);
-      else
-       signo = get_detach_signal (main_lwp);
+      /* Pass on any pending signal for the last LWP.  */
+      int signo = get_detach_signal (main_lwp);
 
       detach_one_lwp (main_lwp, &signo);
 
-      inf_ptrace_detach_success (ops);
+      inf_ptrace_detach_success (ops, inf);
     }
 }
 
@@ -2161,6 +2152,30 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
                  _("unknown ptrace event %d"), event);
 }
 
+/* Suspend waiting for a signal.  We're mostly interested in
+   SIGCHLD/SIGINT.  */
+
+static void
+wait_for_signal ()
+{
+  if (debug_linux_nat)
+    fprintf_unfiltered (gdb_stdlog, "linux-nat: about to sigsuspend\n");
+  sigsuspend (&suspend_mask);
+
+  /* If the quit flag is set, it means that the user pressed Ctrl-C
+     and we're debugging a process that is running on a separate
+     terminal, so we must forward the Ctrl-C to the inferior.  (If the
+     inferior is sharing GDB's terminal, then the Ctrl-C reaches the
+     inferior directly.)  We must do this here because functions that
+     need to block waiting for a signal loop forever until there's an
+     event to report before returning back to the event loop.  */
+  if (!target_terminal::is_ours ())
+    {
+      if (check_quit_flag ())
+       target_pass_ctrlc ();
+    }
+}
+
 /* Wait for LP to stop.  Returns the wait status, or 0 if the LWP has
    exited.  */
 
@@ -2226,10 +2241,7 @@ wait_lwp (struct lwp_info *lp)
         linux_nat_wait_1 and there if we get called my_waitpid gets called
         again before it gets to sigsuspend so we can safely let the handlers
         get executed here.  */
-
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog, "WL: about to sigsuspend\n");
-      sigsuspend (&suspend_mask);
+      wait_for_signal ();
     }
 
   restore_child_signals_mask (&prev_mask);
@@ -3413,9 +3425,7 @@ linux_nat_wait_1 (struct target_ops *ops,
       gdb_assert (lp == NULL);
 
       /* Block until we get an event reported with SIGCHLD.  */
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog, "LNW: about to sigsuspend\n");
-      sigsuspend (&suspend_mask);
+      wait_for_signal ();
     }
 
   gdb_assert (lp);
@@ -4281,17 +4291,17 @@ cleanup_target_stop (void *arg)
   target_continue_no_signal (*ptid);
 }
 
-static VEC(static_tracepoint_marker_p) *
+static std::vector<static_tracepoint_marker>
 linux_child_static_tracepoint_markers_by_strid (struct target_ops *self,
                                                const char *strid)
 {
   char s[IPA_CMD_BUF_SIZE];
   struct cleanup *old_chain;
   int pid = ptid_get_pid (inferior_ptid);
-  VEC(static_tracepoint_marker_p) *markers = NULL;
-  struct static_tracepoint_marker *marker = NULL;
+  std::vector<static_tracepoint_marker> markers;
   const char *p = s;
   ptid_t ptid = ptid_build (pid, 0, 0);
+  static_tracepoint_marker marker;
 
   /* Pause all */
   target_stop (ptid);
@@ -4301,29 +4311,16 @@ linux_child_static_tracepoint_markers_by_strid (struct target_ops *self,
 
   agent_run_command (pid, s, strlen (s) + 1);
 
-  old_chain = make_cleanup (free_current_marker, &marker);
-  make_cleanup (cleanup_target_stop, &ptid);
+  old_chain = make_cleanup (cleanup_target_stop, &ptid);
 
   while (*p++ == 'm')
     {
-      if (marker == NULL)
-       marker = XCNEW (struct static_tracepoint_marker);
-
       do
        {
-         parse_static_tracepoint_marker_definition (p, &p, marker);
+         parse_static_tracepoint_marker_definition (p, &p, &marker);
 
-         if (strid == NULL || strcmp (strid, marker->str_id) == 0)
-           {
-             VEC_safe_push (static_tracepoint_marker_p,
-                            markers, marker);
-             marker = NULL;
-           }
-         else
-           {
-             release_static_tracepoint_marker (marker);
-             memset (marker, 0, sizeof (*marker));
-           }
+         if (strid == NULL || marker.str_id == strid)
+           markers.push_back (std::move (marker));
        }
       while (*p++ == ',');     /* comma-separated list */
 
@@ -4438,49 +4435,6 @@ linux_nat_supports_disable_randomization (struct target_ops *self)
 #endif
 }
 
-static int async_terminal_is_ours = 1;
-
-/* target_terminal_inferior implementation.
-
-   This is a wrapper around child_terminal_inferior to add async support.  */
-
-static void
-linux_nat_terminal_inferior (struct target_ops *self)
-{
-  child_terminal_inferior (self);
-
-  /* Calls to target_terminal_*() are meant to be idempotent.  */
-  if (!async_terminal_is_ours)
-    return;
-
-  async_terminal_is_ours = 0;
-  set_sigint_trap ();
-}
-
-/* target_terminal::ours implementation.
-
-   This is a wrapper around child_terminal_ours to add async support (and
-   implement the target_terminal::ours vs target_terminal::ours_for_output
-   distinction).  child_terminal_ours is currently no different than
-   child_terminal_ours_for_output.
-   We leave target_terminal::ours_for_output alone, leaving it to
-   child_terminal_ours_for_output.  */
-
-static void
-linux_nat_terminal_ours (struct target_ops *self)
-{
-  /* GDB should never give the terminal to the inferior if the
-     inferior is running in the background (run&, continue&, etc.),
-     but claiming it sure should.  */
-  child_terminal_ours (self);
-
-  if (async_terminal_is_ours)
-    return;
-
-  clear_sigint_trap ();
-  async_terminal_is_ours = 1;
-}
-
 /* SIGCHLD handler that serves two purposes: In non-stop/async mode,
    so we notice when any child changes state, and notify the
    event-loop; it allows us to use sigsuspend in linux_nat_wait_1
@@ -4742,27 +4696,23 @@ linux_nat_fileio_open (struct target_ops *self,
 
 /* Implementation of to_fileio_readlink.  */
 
-static char *
+static gdb::optional<std::string>
 linux_nat_fileio_readlink (struct target_ops *self,
                           struct inferior *inf, const char *filename,
                           int *target_errno)
 {
   char buf[PATH_MAX];
   int len;
-  char *ret;
 
   len = linux_mntns_readlink (linux_nat_fileio_pid_of (inf),
                              filename, buf, sizeof (buf));
   if (len < 0)
     {
       *target_errno = host_to_fileio_error (errno);
-      return NULL;
+      return {};
     }
 
-  ret = (char *) xmalloc (len + 1);
-  memcpy (ret, buf, len);
-  ret[len] = '\0';
-  return ret;
+  return std::string (buf, len);
 }
 
 /* Implementation of to_fileio_unlink.  */
@@ -4829,8 +4779,6 @@ linux_nat_add_target (struct target_ops *t)
   t->to_supports_non_stop = linux_nat_supports_non_stop;
   t->to_always_non_stop_p = linux_nat_always_non_stop_p;
   t->to_async = linux_nat_async;
-  t->to_terminal_inferior = linux_nat_terminal_inferior;
-  t->to_terminal_ours = linux_nat_terminal_ours;
 
   super_close = t->to_close;
   t->to_close = linux_nat_close;
This page took 0.026338 seconds and 4 git commands to generate.