opcodes error messages
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index 73ef2d49473e9d1761e8391bd7acfeeb1a15cc02..cc930c63347f8221aa344389a38dc214b54934cd 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   Copyright (C) 2001-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -197,6 +197,9 @@ static struct target_ops linux_ops_saved;
 /* The method to call, if any, when a new thread is attached.  */
 static void (*linux_nat_new_thread) (struct lwp_info *);
 
+/* The method to call, if any, when a thread is destroyed.  */
+static void (*linux_nat_delete_thread) (struct arch_lwp_info *);
+
 /* The method to call, if any, when a new fork is attached.  */
 static linux_nat_new_fork_ftype *linux_nat_new_fork;
 
@@ -477,7 +480,6 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
     {
       struct lwp_info *child_lp = NULL;
       int status = W_STOPCODE (0);
-      struct cleanup *old_chain;
       int has_vforked;
       ptid_t parent_ptid, child_ptid;
       int parent_pid, child_pid;
@@ -490,16 +492,15 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
       child_pid = ptid_get_lwp (child_ptid);
 
       /* We're already attached to the parent, by default.  */
-      old_chain = save_inferior_ptid ();
-      inferior_ptid = child_ptid;
-      child_lp = add_lwp (inferior_ptid);
+      child_lp = add_lwp (child_ptid);
       child_lp->stopped = 1;
       child_lp->last_resume_kind = resume_stop;
 
       /* Detach new forked process?  */
       if (detach_fork)
        {
-         make_cleanup (delete_lwp_cleanup, child_lp);
+         struct cleanup *old_chain = make_cleanup (delete_lwp_cleanup,
+                                                   child_lp);
 
          if (linux_nat_prepare_to_resume != NULL)
            linux_nat_prepare_to_resume (child_lp);
@@ -512,8 +513,11 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
             To work around this, single step the child process
             once before detaching to clear the flags.  */
 
+         /* Note that we consult the parent's architecture instead of
+            the child's because there's no inferior for the child at
+            this point.  */
          if (!gdbarch_software_single_step_p (target_thread_architecture
-                                                  (child_lp->ptid)))
+                                              (parent_ptid)))
            {
              linux_disable_event_reporting (child_pid);
              if (ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0) < 0)
@@ -533,17 +537,18 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
              ptrace (PTRACE_DETACH, child_pid, 0, signo);
            }
 
-         /* Resets value of inferior_ptid to parent ptid.  */
          do_cleanups (old_chain);
        }
       else
        {
+         scoped_restore save_inferior_ptid
+           = make_scoped_restore (&inferior_ptid);
+         inferior_ptid = child_ptid;
+
          /* Let the thread_db layer learn about this new process.  */
          check_for_thread_db ();
        }
 
-      do_cleanups (old_chain);
-
       if (has_vforked)
        {
          struct lwp_info *parent_lp;
@@ -671,8 +676,8 @@ linux_child_remove_exec_catchpoint (struct target_ops *self, int pid)
 
 static int
 linux_child_set_syscall_catchpoint (struct target_ops *self,
-                                   int pid, int needed, int any_count,
-                                   int table_size, int *table)
+                                   int pid, bool needed, int any_count,
+                                   gdb::array_view<const int> syscall_counts)
 {
   if (!linux_supports_tracesysgood ())
     return 1;
@@ -680,7 +685,7 @@ linux_child_set_syscall_catchpoint (struct target_ops *self,
   /* On GNU/Linux, we ignore the arguments.  It means that we only
      enable the syscall catchpoints, but do not disable them.
 
-     Also, we do not use the `table' information because we do not
+     Also, we do not use the `syscall_counts' information because we do not
      filter system calls here.  We let GDB do the logic for us.  */
   return 0;
 }
@@ -837,7 +842,12 @@ static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 static void
 lwp_free (struct lwp_info *lp)
 {
-  xfree (lp->arch_private);
+  /* Let the arch specific bits release arch_lwp_info.  */
+  if (linux_nat_delete_thread != NULL)
+    linux_nat_delete_thread (lp->arch_private);
+  else
+    gdb_assert (lp->arch_private == NULL);
+
   xfree (lp);
 }
 
@@ -1045,7 +1055,7 @@ exit_lwp (struct lwp_info *lp)
    Returns a wait status for that LWP, to cache.  */
 
 static int
-linux_nat_post_attach_wait (ptid_t ptid, int first, int *signalled)
+linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
 {
   pid_t new_pid, pid = ptid_get_lwp (ptid);
   int status;
@@ -1105,11 +1115,11 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *signalled)
 
 static void
 linux_nat_create_inferior (struct target_ops *ops, 
-                          char *exec_file, char *allargs, char **env,
-                          int from_tty)
+                          const char *exec_file, const std::string &allargs,
+                          char **env, int from_tty)
 {
-  struct cleanup *restore_personality
-    = maybe_disable_address_space_randomization (disable_randomization);
+  maybe_disable_address_space_randomization restore_personality
+    (disable_randomization);
 
   /* The fork_child mechanism is synchronous and calls target_wait, so
      we have to mask the async mode.  */
@@ -1118,8 +1128,6 @@ linux_nat_create_inferior (struct target_ops *ops,
   linux_nat_pass_signals (ops, 0, NULL);
 
   linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
-
-  do_cleanups (restore_personality);
 }
 
 /* Callback for linux_proc_attach_tgid_threads.  Attach to PTID if not
@@ -1159,10 +1167,11 @@ attach_proc_task_lwp_callback (ptid_t ptid)
            }
          else
            {
+             std::string reason
+               = linux_ptrace_attach_fail_reason_string (ptid, err);
+
              warning (_("Cannot attach to lwp %d: %s"),
-                      lwpid,
-                      linux_ptrace_attach_fail_reason_string (ptid,
-                                                              err));
+                      lwpid, reason.c_str ());
            }
        }
       else
@@ -1215,23 +1224,12 @@ linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
   CATCH (ex, RETURN_MASK_ERROR)
     {
       pid_t pid = parse_pid_to_attach (args);
-      struct buffer buffer;
-      char *message, *buffer_s;
-
-      message = xstrdup (ex.message);
-      make_cleanup (xfree, message);
+      std::string reason = linux_ptrace_attach_fail_reason (pid);
 
-      buffer_init (&buffer);
-      linux_ptrace_attach_fail_reason (pid, &buffer);
-
-      buffer_grow_str0 (&buffer, "");
-      buffer_s = buffer_finish (&buffer);
-      make_cleanup (xfree, buffer_s);
-
-      if (*buffer_s != '\0')
-       throw_error (ex.error, "warning: %s\n%s", buffer_s, message);
+      if (!reason.empty ())
+       throw_error (ex.error, "warning: %s\n%s", reason.c_str (), ex.message);
       else
-       throw_error (ex.error, "%s", message);
+       throw_error (ex.error, "%s", ex.message);
     }
   END_CATCH
 
@@ -1245,14 +1243,14 @@ linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
   /* Add the initial process as the first LWP to the list.  */
   lp = add_initial_lwp (ptid);
 
-  status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->signalled);
+  status = linux_nat_post_attach_wait (lp->ptid, &lp->signalled);
   if (!WIFSTOPPED (status))
     {
       if (WIFEXITED (status))
        {
          int exit_code = WEXITSTATUS (status);
 
-         target_terminal_ours ();
+         target_terminal::ours ();
          target_mourn_inferior (inferior_ptid);
          if (exit_code == 0)
            error (_("Unable to attach: program exited normally."));
@@ -1264,7 +1262,7 @@ linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
        {
          enum gdb_signal signo;
 
-         target_terminal_ours ();
+         target_terminal::ours ();
          target_mourn_inferior (inferior_ptid);
 
          signo = gdb_signal_from_host (WTERMSIG (status));
@@ -1499,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. */
@@ -1519,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));
 
@@ -1529,27 +1525,19 @@ 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);
     }
-  delete_lwp (main_lwp->ptid);
 }
 
 /* Resume execution of the inferior process.  If STEP is nonzero,
@@ -2164,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.  */
 
@@ -2229,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);
@@ -2459,12 +2468,10 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
 static int
 check_stopped_by_watchpoint (struct lwp_info *lp)
 {
-  struct cleanup *old_chain;
-
   if (linux_ops->to_stopped_by_watchpoint == NULL)
     return 0;
 
-  old_chain = save_inferior_ptid ();
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
   inferior_ptid = lp->ptid;
 
   if (linux_ops->to_stopped_by_watchpoint (linux_ops))
@@ -2479,8 +2486,6 @@ check_stopped_by_watchpoint (struct lwp_info *lp)
        lp->stopped_data_address_p = 0;
     }
 
-  do_cleanups (old_chain);
-
   return lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
@@ -2637,7 +2642,7 @@ status_callback (struct lwp_info *lp, void *data)
        }
 
 #if !USE_SIGTRAP_SIGINFO
-      else if (!breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+      else if (!breakpoint_inserted_here_p (regcache->aspace (), pc))
        {
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
@@ -2745,7 +2750,7 @@ save_stop_reason (struct lwp_info *lp)
     return;
 
   regcache = get_thread_regcache (lp->ptid);
-  gdbarch = get_regcache_arch (regcache);
+  gdbarch = regcache->arch ();
 
   pc = regcache_read_pc (regcache);
   sw_bp_pc = pc - gdbarch_decr_pc_after_break (gdbarch);
@@ -2797,7 +2802,7 @@ save_stop_reason (struct lwp_info *lp)
     }
 #else
   if ((!lp->step || lp->stop_pc == sw_bp_pc)
-      && software_breakpoint_inserted_here_p (get_regcache_aspace (regcache),
+      && software_breakpoint_inserted_here_p (regcache->aspace (),
                                              sw_bp_pc))
     {
       /* The LWP was either continued, or stepped a software
@@ -2805,7 +2810,7 @@ save_stop_reason (struct lwp_info *lp)
       lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
     }
 
-  if (hardware_breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+  if (hardware_breakpoint_inserted_here_p (regcache->aspace (), pc))
     lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
 
   if (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON)
@@ -3420,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);
@@ -3455,7 +3458,7 @@ linux_nat_wait_1 (struct target_ops *ops,
       && !USE_SIGTRAP_SIGINFO)
     {
       struct regcache *regcache = get_thread_regcache (lp->ptid);
-      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct gdbarch *gdbarch = regcache->arch ();
       int decr_pc = gdbarch_decr_pc_after_break (gdbarch);
 
       if (decr_pc != 0)
@@ -3558,7 +3561,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
   else
     {
       struct regcache *regcache = get_thread_regcache (lp->ptid);
-      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct gdbarch *gdbarch = regcache->arch ();
 
       TRY
        {
@@ -3569,7 +3572,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
             immediately, and we're not waiting for this LWP.  */
          if (!ptid_match (lp->ptid, *wait_ptid_p))
            {
-             if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+             if (breakpoint_inserted_here_p (regcache->aspace (), pc))
                leave_stopped = 1;
            }
 
@@ -3890,7 +3893,6 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
                        const gdb_byte *writebuf,
                        ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  struct cleanup *old_chain;
   enum target_xfer_status xfer;
 
   if (object == TARGET_OBJECT_SIGNAL_INFO)
@@ -3903,15 +3905,9 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_MEMORY && ptid_equal (inferior_ptid, null_ptid))
     return TARGET_XFER_EOF;
 
-  old_chain = save_inferior_ptid ();
-
-  if (ptid_lwp_p (inferior_ptid))
-    inferior_ptid = pid_to_ptid (ptid_get_lwp (inferior_ptid));
-
   xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
                                     offset, len, xfered_len);
 
-  do_cleanups (old_chain);
   return xfer;
 }
 
@@ -3947,7 +3943,7 @@ linux_nat_update_thread_list (struct target_ops *ops)
     }
 }
 
-static char *
+static const char *
 linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   static char buf[64];
@@ -4001,8 +3997,8 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
 
   /* We could keep this file open and cache it - possibly one per
      thread.  That requires some juggling, but is even faster.  */
-  xsnprintf (filename, sizeof filename, "/proc/%d/mem",
-            ptid_get_pid (inferior_ptid));
+  xsnprintf (filename, sizeof filename, "/proc/%ld/mem",
+            ptid_get_lwp (inferior_ptid));
   fd = gdb_open_cloexec (filename, ((readbuf ? O_RDONLY : O_WRONLY)
                                    | O_LARGEFILE), 0);
   if (fd == -1)
@@ -4095,7 +4091,7 @@ linux_proc_xfer_spu (struct target_ops *ops, enum target_object object,
   char buf[128];
   int fd = 0;
   int ret = -1;
-  int pid = ptid_get_pid (inferior_ptid);
+  int pid = ptid_get_lwp (inferior_ptid);
 
   if (!annex)
     {
@@ -4195,20 +4191,17 @@ void
 linux_proc_pending_signals (int pid, sigset_t *pending,
                            sigset_t *blocked, sigset_t *ignored)
 {
-  FILE *procfile;
   char buffer[PATH_MAX], fname[PATH_MAX];
-  struct cleanup *cleanup;
 
   sigemptyset (pending);
   sigemptyset (blocked);
   sigemptyset (ignored);
   xsnprintf (fname, sizeof fname, "/proc/%d/status", pid);
-  procfile = gdb_fopen_cloexec (fname, "r");
+  gdb_file_up procfile = gdb_fopen_cloexec (fname, "r");
   if (procfile == NULL)
     error (_("Could not open %s"), fname);
-  cleanup = make_cleanup_fclose (procfile);
 
-  while (fgets (buffer, PATH_MAX, procfile) != NULL)
+  while (fgets (buffer, PATH_MAX, procfile.get ()) != NULL)
     {
       /* Normal queued signals are on the SigPnd line in the status
         file.  However, 2.6 kernels also have a "shared" pending
@@ -4227,8 +4220,6 @@ linux_proc_pending_signals (int pid, sigset_t *pending,
       else if (startswith (buffer, "SigIgn:\t"))
        add_line_to_sigset (buffer + 8, ignored);
     }
-
-  do_cleanups (cleanup);
 }
 
 static enum target_xfer_status
@@ -4309,7 +4300,7 @@ linux_child_static_tracepoint_markers_by_strid (struct target_ops *self,
   int pid = ptid_get_pid (inferior_ptid);
   VEC(static_tracepoint_marker_p) *markers = NULL;
   struct static_tracepoint_marker *marker = NULL;
-  char *p = s;
+  const char *p = s;
   ptid_t ptid = ptid_build (pid, 0, 0);
 
   /* Pause all */
@@ -4457,49 +4448,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
@@ -4848,8 +4796,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;
@@ -4888,6 +4834,17 @@ linux_nat_set_new_thread (struct target_ops *t,
   linux_nat_new_thread = new_thread;
 }
 
+/* Register a method to call whenever a new thread is attached.  */
+void
+linux_nat_set_delete_thread (struct target_ops *t,
+                            void (*delete_thread) (struct arch_lwp_info *))
+{
+  /* Save the pointer.  We only support a single registered instance
+     of the GNU/Linux native target, so we do not need to map this to
+     T.  */
+  linux_nat_delete_thread = delete_thread;
+}
+
 /* See declaration in linux-nat.h.  */
 
 void
@@ -4970,9 +4927,6 @@ current_lwp_ptid (void)
   return inferior_ptid;
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_linux_nat;
-
 void
 _initialize_linux_nat (void)
 {
This page took 0.031268 seconds and 4 git commands to generate.