Add set/show debug dwarf-line.
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index 803bdf6b1e299c31fa85df4b91a8e61151749529..f95e76c601084ecd67abbed02890ff14aea4a6df 100644 (file)
@@ -368,6 +368,25 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
   return 0;
 }
 
+/* Return the ptrace options that we want to try to enable.  */
+
+static int
+linux_nat_ptrace_options (int attached)
+{
+  int options = 0;
+
+  if (!attached)
+    options |= PTRACE_O_EXITKILL;
+
+  options |= (PTRACE_O_TRACESYSGOOD
+             | PTRACE_O_TRACEVFORKDONE
+             | PTRACE_O_TRACEVFORK
+             | PTRACE_O_TRACEFORK
+             | PTRACE_O_TRACEEXEC);
+
+  return options;
+}
+
 /* Initialize ptrace warnings and check for supported ptrace
    features given PID.
 
@@ -376,7 +395,9 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
 static void
 linux_init_ptrace (pid_t pid, int attached)
 {
-  linux_enable_event_reporting (pid, attached);
+  int options = linux_nat_ptrace_options (attached);
+
+  linux_enable_event_reporting (pid, options);
   linux_ptrace_init_warnings ();
 }
 
@@ -1341,7 +1362,7 @@ linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
                                  attach_proc_task_lwp_callback);
 
   if (target_can_async_p ())
-    target_async (inferior_event_handler, 0);
+    target_async (1);
 }
 
 /* Get pending status of LP.  */
@@ -1789,7 +1810,7 @@ linux_nat_resume (struct target_ops *ops,
 
       if (target_can_async_p ())
        {
-         target_async (inferior_event_handler, 0);
+         target_async (1);
          /* Tell the event loop we have something to process.  */
          async_file_mark ();
        }
@@ -1799,18 +1820,18 @@ linux_nat_resume (struct target_ops *ops,
   if (resume_many)
     iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
 
-  linux_resume_one_lwp (lp, step, signo);
-
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
                        "LLR: %s %s, %s (resume event thread)\n",
                        step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
-                       target_pid_to_str (ptid),
+                       target_pid_to_str (lp->ptid),
                        (signo != GDB_SIGNAL_0
                         ? strsignal (gdb_signal_to_host (signo)) : "0"));
 
+  linux_resume_one_lwp (lp, step, signo);
+
   if (target_can_async_p ())
-    target_async (inferior_event_handler, 0);
+    target_async (1);
 }
 
 /* Send a signal to an LWP.  */
@@ -2109,9 +2130,12 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
              add_thread (new_lp->ptid);
            }
 
+         /* Even if we're stopping the thread for some reason
+            internal to this module, from the user/frontend's
+            perspective, this new thread is running.  */
+         set_running (new_lp->ptid, 1);
          if (!stopping)
            {
-             set_running (new_lp->ptid, 1);
              set_executing (new_lp->ptid, 1);
              /* thread_db_attach_lwp -> lin_lwp_attach_lwp forced
                 resume_stop.  */
@@ -2298,8 +2322,9 @@ wait_lwp (struct lwp_info *lp)
   if (lp->must_set_ptrace_flags)
     {
       struct inferior *inf = find_inferior_pid (ptid_get_pid (lp->ptid));
+      int options = linux_nat_ptrace_options (inf->attach_flag);
 
-      linux_enable_event_reporting (ptid_get_lwp (lp->ptid), inf->attach_flag);
+      linux_enable_event_reporting (ptid_get_lwp (lp->ptid), options);
       lp->must_set_ptrace_flags = 0;
     }
 
@@ -2618,7 +2643,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
-                               "SWC: Delayed SIGSTOP caught for %s.\n",
+                               "SWC: Expected SIGSTOP caught for %s.\n",
                                target_pid_to_str (lp->ptid));
 
          /* Reset SIGNALLED only after the stop_wait_callback call
@@ -2795,8 +2820,8 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
            {
              if (debug_linux_nat)
                fprintf_unfiltered (gdb_stdlog,
-                                   "CSBB: Push back software "
-                                   "breakpoint for %s\n",
+                                   "CSBB: %s stopped by software "
+                                   "breakpoint\n",
                                    target_pid_to_str (lp->ptid));
 
              /* Back up the PC if necessary.  */
@@ -2811,14 +2836,21 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
            {
              if (debug_linux_nat)
                fprintf_unfiltered (gdb_stdlog,
-                                   "CSBB: Push back hardware "
-                                   "breakpoint/watchpoint for %s\n",
+                                   "CSBB: %s stopped by hardware "
+                                   "breakpoint/watchpoint\n",
                                    target_pid_to_str (lp->ptid));
 
              lp->stop_pc = pc;
              lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
              return 1;
            }
+         else if (siginfo.si_code == TRAP_TRACE)
+           {
+             if (debug_linux_nat)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "CSBB: %s stopped by trace\n",
+                                   target_pid_to_str (lp->ptid));
+           }
        }
     }
 #else
@@ -2830,7 +2862,7 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
         breakpoint instruction.  */
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
-                           "CB: Push back software breakpoint for %s\n",
+                           "CSBB: %s stopped by software breakpoint\n",
                            target_pid_to_str (lp->ptid));
 
       /* Back up the PC if necessary.  */
@@ -2846,7 +2878,7 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
     {
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
-                           "CB: Push back hardware breakpoint for %s\n",
+                           "CSBB: stopped by hardware breakpoint %s\n",
                            target_pid_to_str (lp->ptid));
 
       lp->stop_pc = pc;
@@ -3092,8 +3124,9 @@ linux_nat_filter_event (int lwpid, int status)
   if (WIFSTOPPED (status) && lp->must_set_ptrace_flags)
     {
       struct inferior *inf = find_inferior_pid (ptid_get_pid (lp->ptid));
+      int options = linux_nat_ptrace_options (inf->attach_flag);
 
-      linux_enable_event_reporting (ptid_get_lwp (lp->ptid), inf->attach_flag);
+      linux_enable_event_reporting (ptid_get_lwp (lp->ptid), options);
       lp->must_set_ptrace_flags = 0;
     }
 
@@ -3206,28 +3239,28 @@ linux_nat_filter_event (int lwpid, int status)
   if (lp->signalled
       && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: Delayed SIGSTOP caught for %s.\n",
-                           target_pid_to_str (lp->ptid));
-
       lp->signalled = 0;
 
-      if (lp->last_resume_kind != resume_stop)
+      if (lp->last_resume_kind == resume_stop)
        {
-         /* This is a delayed SIGSTOP.  */
+         if (debug_linux_nat)
+           fprintf_unfiltered (gdb_stdlog,
+                               "LLW: resume_stop SIGSTOP caught for %s.\n",
+                               target_pid_to_str (lp->ptid));
+       }
+      else
+       {
+         /* This is a delayed SIGSTOP.  Filter out the event.  */
 
-         linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
-                               "LLW: %s %s, 0, 0 (discard SIGSTOP)\n",
+                               "LLW: %s %s, 0, 0 (discard delayed SIGSTOP)\n",
                                lp->step ?
                                "PTRACE_SINGLESTEP" : "PTRACE_CONT",
                                target_pid_to_str (lp->ptid));
 
+         linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
          gdb_assert (lp->resumed);
-
-         /* Discard the event.  */
          return NULL;
        }
     }
@@ -4020,6 +4053,23 @@ linux_nat_thread_alive (struct target_ops *ops, ptid_t ptid)
   return linux_thread_alive (ptid);
 }
 
+/* Implement the to_update_thread_list target method for this
+   target.  */
+
+static void
+linux_nat_update_thread_list (struct target_ops *ops)
+{
+  if (linux_supports_traceclone ())
+    {
+      /* With support for clone events, we add/delete threads from the
+        list as clone/exit events are processed, so just try deleting
+        exited threads still in the thread list.  */
+      delete_exited_threads ();
+    }
+  else
+    prune_threads ();
+}
+
 static char *
 linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
@@ -4079,15 +4129,7 @@ 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)
 {
-  static char buf[PATH_MAX];
-  char name[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);
-
-  return buf;
+  return linux_proc_pid_to_exec_file (pid);
 }
 
 /* Implement the to_xfer_partial interface for memory reads using the /proc
@@ -4618,10 +4660,6 @@ linux_nat_terminal_ours (struct target_ops *self)
   async_terminal_is_ours = 1;
 }
 
-static void (*async_client_callback) (enum inferior_event_type event_type,
-                                     void *context);
-static void *async_client_context;
-
 /* 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
@@ -4649,7 +4687,7 @@ sigchld_handler (int signo)
 static void
 handle_target_event (int error, gdb_client_data client_data)
 {
-  (*async_client_callback) (INF_REG_EVENT, async_client_context);
+  inferior_event_handler (INF_REG_EVENT, NULL);
 }
 
 /* Create/destroy the target events pipe.  Returns previous state.  */
@@ -4693,15 +4731,10 @@ linux_async_pipe (int enable)
 /* target_async implementation.  */
 
 static void
-linux_nat_async (struct target_ops *ops,
-                void (*callback) (enum inferior_event_type event_type,
-                                  void *context),
-                void *context)
+linux_nat_async (struct target_ops *ops, int enable)
 {
-  if (callback != NULL)
+  if (enable)
     {
-      async_client_callback = callback;
-      async_client_context = context;
       if (!linux_async_pipe (1))
        {
          add_file_handler (linux_nat_event_pipe[0],
@@ -4713,8 +4746,6 @@ linux_nat_async (struct target_ops *ops,
     }
   else
     {
-      async_client_callback = callback;
-      async_client_context = context;
       delete_file_handler (linux_nat_event_pipe[0]);
       linux_async_pipe (0);
     }
@@ -4782,7 +4813,7 @@ linux_nat_close (struct target_ops *self)
 {
   /* Unregister from the event loop.  */
   if (linux_nat_is_async_p (self))
-    linux_nat_async (self, NULL, NULL);
+    linux_nat_async (self, 0);
 
   if (linux_ops->to_close)
     linux_ops->to_close (linux_ops);
@@ -4855,6 +4886,7 @@ linux_nat_add_target (struct target_ops *t)
   t->to_kill = linux_nat_kill;
   t->to_mourn_inferior = linux_nat_mourn_inferior;
   t->to_thread_alive = linux_nat_thread_alive;
+  t->to_update_thread_list = linux_nat_update_thread_list;
   t->to_pid_to_str = linux_nat_pid_to_str;
   t->to_thread_name = linux_nat_thread_name;
   t->to_has_thread_control = tc_schedlock;
@@ -5019,14 +5051,6 @@ Enables printf debugging output."),
   sigdelset (&suspend_mask, SIGCHLD);
 
   sigemptyset (&blocked_mask);
-
-  /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to
-     support read-only process state.  */
-  linux_ptrace_set_additional_flags (PTRACE_O_TRACESYSGOOD
-                                    | PTRACE_O_TRACEVFORKDONE
-                                    | PTRACE_O_TRACEVFORK
-                                    | PTRACE_O_TRACEFORK
-                                    | PTRACE_O_TRACEEXEC);
 }
 \f
 
This page took 0.034599 seconds and 4 git commands to generate.