gdb/testsuite: Don't allow paths to appear in test name
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index 567cb064d3aa1467d835ae28b087f7e9f3133287..73d4fd193ae14b29752dfe024296fb99786474a6 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+   Copyright (C) 2001-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -191,10 +191,6 @@ struct linux_nat_target *linux_target;
 /* Does the current host support PTRACE_GETREGSET?  */
 enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
 
-/* The saved to_close method, inherited from inf-ptrace.c.
-   Called by our to_close.  */
-static void (*super_close) (struct target_ops *);
-
 static unsigned int debug_linux_nat;
 static void
 show_debug_linux_nat (struct ui_file *file, int from_tty,
@@ -384,18 +380,19 @@ linux_nat_ptrace_options (int attached)
   return options;
 }
 
-/* Initialize ptrace warnings and check for supported ptrace
-   features given PID.
+/* Initialize ptrace and procfs warnings and check for supported
+   ptrace features given PID.
 
    ATTACHED should be nonzero iff we attached to the inferior.  */
 
 static void
-linux_init_ptrace (pid_t pid, int attached)
+linux_init_ptrace_procfs (pid_t pid, int attached)
 {
   int options = linux_nat_ptrace_options (attached);
 
   linux_enable_event_reporting (pid, options);
   linux_ptrace_init_warnings ();
+  linux_proc_init_warnings ();
 }
 
 linux_nat_target::~linux_nat_target ()
@@ -404,13 +401,13 @@ linux_nat_target::~linux_nat_target ()
 void
 linux_nat_target::post_attach (int pid)
 {
-  linux_init_ptrace (pid, 1);
+  linux_init_ptrace_procfs (pid, 1);
 }
 
 void
 linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
-  linux_init_ptrace (ptid.pid (), 0);
+  linux_init_ptrace_procfs (ptid.pid (), 0);
 }
 
 /* Return the number of known LWPs in the tgid given by PID.  */
@@ -428,15 +425,19 @@ num_lwps (int pid)
   return count;
 }
 
-/* Call delete_lwp with prototype compatible for make_cleanup.  */
+/* Deleter for lwp_info unique_ptr specialisation.  */
 
-static void
-delete_lwp_cleanup (void *lp_voidp)
+struct lwp_deleter
 {
-  struct lwp_info *lp = (struct lwp_info *) lp_voidp;
+  void operator() (struct lwp_info *lwp) const
+  {
+    delete_lwp (lwp->ptid);
+  }
+};
 
-  delete_lwp (lp->ptid);
-}
+/* A unique_ptr specialisation for lwp_info.  */
+
+typedef std::unique_ptr<struct lwp_info, lwp_deleter> lwp_info_up;
 
 /* Target hook for follow_fork.  On entry inferior_ptid must be the
    ptid of the followed inferior.  At return, inferior_ptid will be
@@ -448,7 +449,6 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
   if (!follow_child)
     {
       struct lwp_info *child_lp = NULL;
-      int status = W_STOPCODE (0);
       int has_vforked;
       ptid_t parent_ptid, child_ptid;
       int parent_pid, child_pid;
@@ -468,10 +468,15 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
       /* Detach new forked process?  */
       if (detach_fork)
        {
-         struct cleanup *old_chain = make_cleanup (delete_lwp_cleanup,
-                                                   child_lp);
+         int child_stop_signal = 0;
+         bool detach_child = true;
 
-         linux_target->low_prepare_to_resume (child_lp);
+         /* Move CHILD_LP into a unique_ptr and clear the source pointer
+            to prevent us doing anything stupid with it.  */
+         lwp_info_up child_lp_ptr (child_lp);
+         child_lp = nullptr;
+
+         linux_target->low_prepare_to_resume (child_lp_ptr.get ());
 
          /* When debugging an inferior in an architecture that supports
             hardware single stepping on a kernel without commit
@@ -487,25 +492,29 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
          if (!gdbarch_software_single_step_p (target_thread_architecture
                                               (parent_ptid)))
            {
+             int status;
+
              linux_disable_event_reporting (child_pid);
              if (ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0) < 0)
                perror_with_name (_("Couldn't do single step"));
              if (my_waitpid (child_pid, &status, 0) < 0)
                perror_with_name (_("Couldn't wait vfork process"));
+             else
+               {
+                 detach_child = WIFSTOPPED (status);
+                 child_stop_signal = WSTOPSIG (status);
+               }
            }
 
-         if (WIFSTOPPED (status))
+         if (detach_child)
            {
-             int signo;
+             int signo = child_stop_signal;
 
-             signo = WSTOPSIG (status);
              if (signo != 0
                  && !signal_pass_state (gdb_signal_from_host (signo)))
                signo = 0;
              ptrace (PTRACE_DETACH, child_pid, 0, signo);
            }
-
-         do_cleanups (old_chain);
        }
       else
        {
@@ -3167,9 +3176,7 @@ linux_nat_filter_event (int lwpid, int status)
 static void
 check_zombie_leaders (void)
 {
-  struct inferior *inf;
-
-  ALL_INFERIORS (inf)
+  for (inferior *inf : all_inferiors ())
     {
       struct lwp_info *leader_lp;
 
@@ -3551,14 +3558,11 @@ linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 
   if (debug_linux_nat)
     {
-      char *options_string;
-
-      options_string = target_options_to_string (target_options);
+      std::string options_string = target_options_to_string (target_options);
       fprintf_unfiltered (gdb_stdlog,
                          "linux_nat_wait: [%s], [%s]\n",
                          target_pid_to_str (ptid),
-                         options_string);
-      xfree (options_string);
+                         options_string.c_str ());
     }
 
   /* Flush the async file first.  */
@@ -3677,28 +3681,25 @@ kill_wait_callback (struct lwp_info *lp, void *data)
 static void
 kill_unfollowed_fork_children (struct inferior *inf)
 {
-  struct thread_info *thread;
+  for (thread_info *thread : inf->non_exited_threads ())
+    {
+      struct target_waitstatus *ws = &thread->pending_follow;
 
-  ALL_NON_EXITED_THREADS (thread)
-    if (thread->inf == inf)
-      {
-       struct target_waitstatus *ws = &thread->pending_follow;
-
-       if (ws->kind == TARGET_WAITKIND_FORKED
-           || ws->kind == TARGET_WAITKIND_VFORKED)
-         {
-           ptid_t child_ptid = ws->value.related_pid;
-           int child_pid = child_ptid.pid ();
-           int child_lwp = child_ptid.lwp ();
-
-           kill_one_lwp (child_lwp);
-           kill_wait_one_lwp (child_lwp);
-
-           /* Let the arch-specific native code know this process is
-              gone.  */
-           linux_target->low_forget_process (child_pid);
-         }
-      }
+      if (ws->kind == TARGET_WAITKIND_FORKED
+         || ws->kind == TARGET_WAITKIND_VFORKED)
+       {
+         ptid_t child_ptid = ws->value.related_pid;
+         int child_pid = child_ptid.pid ();
+         int child_lwp = child_ptid.lwp ();
+
+         kill_one_lwp (child_lwp);
+         kill_wait_one_lwp (child_lwp);
+
+         /* Let the arch-specific native code know this process is
+            gone.  */
+         linux_target->low_forget_process (child_pid);
+       }
+    }
 }
 
 void
This page took 0.026733 seconds and 4 git commands to generate.