Add a TRY_CATCH to get_prev_frame_always to better manage errors during unwind.
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index aeb5582a74a66dfc3f1e3e5244fddb266f375622..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"
@@ -67,6 +68,7 @@
 #include "buffer.h"
 #include "target-descriptions.h"
 #include "filestuff.h"
+#include "objfiles.h"
 
 #ifndef SPUFS_MAGIC
 #define SPUFS_MAGIC 0x23c9b64e
@@ -200,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,
@@ -847,31 +853,6 @@ static int linux_thread_alive (ptid_t ptid);
 static char *linux_child_pid_to_exec_file (struct target_ops *self, int pid);
 
 \f
-/* Convert wait status STATUS to a string.  Used for printing debug
-   messages only.  */
-
-static char *
-status_to_str (int status)
-{
-  static char buf[64];
-
-  if (WIFSTOPPED (status))
-    {
-      if (WSTOPSIG (status) == SYSCALL_SIGTRAP)
-       snprintf (buf, sizeof (buf), "%s (stopped at syscall)",
-                 strsignal (SIGTRAP));
-      else
-       snprintf (buf, sizeof (buf), "%s (stopped)",
-                 strsignal (WSTOPSIG (status)));
-    }
-  else if (WIFSIGNALED (status))
-    snprintf (buf, sizeof (buf), "%s (terminated)",
-             strsignal (WTERMSIG (status)));
-  else
-    snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status));
-
-  return buf;
-}
 
 /* Destroy and free LP.  */
 
@@ -1344,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)
@@ -1663,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;
@@ -1785,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));
@@ -1799,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,
@@ -1885,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;
     }
 
@@ -1968,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;
 }
 
@@ -2177,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;
        }
 
@@ -2332,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)
@@ -2585,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) "
@@ -2611,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
        {
@@ -2625,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;
@@ -2954,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)
     {
@@ -2996,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);
        }
@@ -3341,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))
                {
@@ -3364,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;
@@ -4035,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
@@ -4592,11 +4567,11 @@ linux_nat_terminal_inferior (struct target_ops *self)
   if (!target_is_async_p ())
     {
       /* Async mode is disabled.  */
-      terminal_inferior (self);
+      child_terminal_inferior (self);
       return;
     }
 
-  terminal_inferior (self);
+  child_terminal_inferior (self);
 
   /* Calls to target_terminal_*() are meant to be idempotent.  */
   if (!async_terminal_is_ours)
@@ -4615,14 +4590,14 @@ linux_nat_terminal_ours (struct target_ops *self)
   if (!target_is_async_p ())
     {
       /* Async mode is disabled.  */
-      terminal_ours (self);
+      child_terminal_ours (self);
       return;
     }
 
   /* 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.  */
-  terminal_ours (self);
+  child_terminal_ours (self);
 
   if (async_terminal_is_ours)
     return;
@@ -4800,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
@@ -4881,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.  */
@@ -5031,14 +5010,14 @@ Enables printf debugging output."),
 static int
 get_signo (const char *name)
 {
-  struct minimal_symbol *ms;
+  struct bound_minimal_symbol ms;
   int signo;
 
   ms = lookup_minimal_symbol (name, NULL, NULL);
-  if (ms == NULL)
+  if (ms.minsym == NULL)
     return 0;
 
-  if (target_read_memory (MSYMBOL_VALUE_ADDRESS (ms), (gdb_byte *) &signo,
+  if (target_read_memory (BMSYMBOL_VALUE_ADDRESS (ms), (gdb_byte *) &signo,
                          sizeof (signo)) != 0)
     return 0;
 
This page took 0.027189 seconds and 4 git commands to generate.