Add a TRY_CATCH to get_prev_frame_always to better manage errors during unwind.
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index b615423fafd35512e0375a8e9979f8611d282624..3f6e5ea73195c9c96635cc974e17f298cc8f2de9 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "defs.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "target.h"
 #include "nat/linux-nat.h"
 #include "nat/linux-waitpid.h"
@@ -201,6 +202,10 @@ static int (*linux_nat_siginfo_fixup) (siginfo_t *,
    Called by our to_xfer_partial.  */
 static target_xfer_partial_ftype *super_xfer_partial;
 
+/* 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,
@@ -1320,13 +1325,16 @@ linux_nat_attach (struct target_ops *ops, char *args, int from_tty)
       make_cleanup (xfree, message);
 
       buffer_init (&buffer);
-      linux_ptrace_attach_warnings (pid, &buffer);
+      linux_ptrace_attach_fail_reason (pid, &buffer);
 
       buffer_grow_str0 (&buffer, "");
       buffer_s = buffer_finish (&buffer);
       make_cleanup (xfree, buffer_s);
 
-      throw_error (ex.error, "%s%s", buffer_s, message);
+      if (*buffer_s != '\0')
+       throw_error (ex.error, "warning: %s\n%s", buffer_s, message);
+      else
+       throw_error (ex.error, "%s", message);
     }
 
   /* The ptrace base target adds the main thread with (pid,0,0)
@@ -1639,13 +1647,17 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
     }
 }
 
-/* Resume LWP, with the last stop signal, if it is in pass state.  */
+/* Callback for iterate_over_lwps.  If LWP is EXCEPT, do nothing.
+   Resume LWP with the last stop signal, if it is in pass state.  */
 
 static int
-linux_nat_resume_callback (struct lwp_info *lp, void *data)
+linux_nat_resume_callback (struct lwp_info *lp, void *except)
 {
   enum gdb_signal signo = GDB_SIGNAL_0;
 
+  if (lp == except)
+    return 0;
+
   if (lp->stopped)
     {
       struct thread_info *thread;
@@ -1761,12 +1773,8 @@ linux_nat_resume (struct target_ops *ops,
       return;
     }
 
-  /* Mark LWP as not stopped to prevent it from being continued by
-     linux_nat_resume_callback.  */
-  lp->stopped = 0;
-
   if (resume_many)
-    iterate_over_lwps (ptid, linux_nat_resume_callback, NULL);
+    iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
 
   /* Convert to something the lower layer understands.  */
   ptid = pid_to_ptid (ptid_get_lwp (lp->ptid));
@@ -1775,6 +1783,7 @@ linux_nat_resume (struct target_ops *ops,
     linux_nat_prepare_to_resume (lp);
   linux_ops->to_resume (linux_ops, ptid, step, signo);
   lp->stopped_by_watchpoint = 0;
+  lp->stopped = 0;
 
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
@@ -1861,6 +1870,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
 
       lp->syscall_state = TARGET_WAITKIND_IGNORE;
       ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0);
+      lp->stopped = 0;
       return 1;
     }
 
@@ -1944,6 +1954,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
     linux_nat_prepare_to_resume (lp);
   linux_ops->to_resume (linux_ops, pid_to_ptid (ptid_get_lwp (lp->ptid)),
                        lp->step, GDB_SIGNAL_0);
+  lp->stopped = 0;
   return 1;
 }
 
@@ -2153,7 +2164,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
          linux_ops->to_resume (linux_ops,
                                pid_to_ptid (ptid_get_lwp (lp->ptid)),
                                0, GDB_SIGNAL_0);
-
+         lp->stopped = 0;
          return 1;
        }
 
@@ -2308,6 +2319,7 @@ wait_lwp (struct lwp_info *lp)
     }
 
   gdb_assert (WIFSTOPPED (status));
+  lp->stopped = 1;
 
   /* Handle GNU/Linux's syscall SIGTRAPs.  */
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SYSCALL_SIGTRAP)
@@ -2561,6 +2573,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
          errno = 0;
          ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0);
+         lp->stopped = 0;
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
                                "PTRACE_CONT %s, 0, 0 (%s) "
@@ -2587,9 +2600,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
          /* Save the sigtrap event.  */
          lp->status = status;
-         gdb_assert (!lp->stopped);
          gdb_assert (lp->signalled);
-         lp->stopped = 1;
        }
       else
        {
@@ -2601,8 +2612,6 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                "SWC: Delayed SIGSTOP caught for %s.\n",
                                target_pid_to_str (lp->ptid));
 
-         lp->stopped = 1;
-
          /* Reset SIGNALLED only after the stop_wait_callback call
             above as it does gdb_assert on SIGNALLED.  */
          lp->signalled = 0;
@@ -2930,6 +2939,10 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p)
   if (!WIFSTOPPED (status) && !lp)
     return NULL;
 
+  /* This LWP is stopped now.  (And if dead, this prevents it from
+     ever being continued.)  */
+  lp->stopped = 1;
+
   /* Handle GNU/Linux's syscall SIGTRAPs.  */
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SYSCALL_SIGTRAP)
     {
@@ -2972,7 +2985,6 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p)
         used.  */
       if (ptid_get_pid (lp->ptid) == ptid_get_lwp (lp->ptid))
        {
-         lp->stopped = 1;
          iterate_over_lwps (pid_to_ptid (ptid_get_pid (lp->ptid)),
                             stop_and_resume_callback, new_pending_p);
        }
@@ -3317,13 +3329,9 @@ retry:
                                     " cancelled it\n",
                                     ptid_get_lwp (lp->ptid));
                        }
-                     lp->stopped = 1;
                    }
                  else
-                   {
-                     lp->stopped = 1;
-                     lp->signalled = 0;
-                   }
+                   lp->signalled = 0;
                }
              else if (WIFEXITED (lp->status) || WIFSIGNALED (lp->status))
                {
@@ -3340,11 +3348,6 @@ retry:
                     pending for the next time we're able to report
                     it.  */
 
-                 /* Prevent trying to stop this thread again.  We'll
-                    never try to resume it because it has a pending
-                    status.  */
-                 lp->stopped = 1;
-
                  /* Dead LWP's aren't expected to reported a pending
                     sigstop.  */
                  lp->signalled = 0;
@@ -4011,19 +4014,15 @@ linux_nat_thread_name (struct target_ops *self, struct thread_info *thr)
 static char *
 linux_child_pid_to_exec_file (struct target_ops *self, int pid)
 {
-  char *name1, *name2;
+  static char buf[PATH_MAX];
+  char name[PATH_MAX];
 
-  name1 = xmalloc (PATH_MAX);
-  name2 = xmalloc (PATH_MAX);
-  make_cleanup (xfree, name1);
-  make_cleanup (xfree, name2);
-  memset (name2, 0, PATH_MAX);
+  xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);
+  memset (buf, 0, PATH_MAX);
+  if (readlink (name, buf, PATH_MAX - 1) <= 0)
+    strcpy (buf, name);
 
-  xsnprintf (name1, PATH_MAX, "/proc/%d/exe", pid);
-  if (readlink (name1, name2, PATH_MAX - 1) > 0)
-    return name2;
-  else
-    return name1;
+  return buf;
 }
 
 /* Records the thread's register state for the corefile note
@@ -4776,6 +4775,8 @@ linux_nat_close (struct target_ops *self)
 
   if (linux_ops->to_close)
     linux_ops->to_close (linux_ops);
+
+  super_close (self);
 }
 
 /* When requests are passed down from the linux-nat layer to the
@@ -4857,6 +4858,8 @@ linux_nat_add_target (struct target_ops *t)
   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;
 
   /* Methods for non-stop support.  */
This page took 0.026792 seconds and 4 git commands to generate.