gdbserver: fix killed-outside.exp
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index 41ab510fa4ac5654f101f08efb68e26b5bc5dbd7..07cb83120d310570cbbef4c7d409426c00f3f034 100644 (file)
@@ -447,6 +447,8 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
   struct thread_info *event_thr = get_lwp_thread (event_lwp);
   struct lwp_info *new_lwp;
 
+  gdb_assert (event_lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+
   if ((event == PTRACE_EVENT_FORK) || (event == PTRACE_EVENT_VFORK)
       || (event == PTRACE_EVENT_CLONE))
     {
@@ -577,6 +579,12 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
+      else if (report_thread_events)
+       {
+         new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+         new_lwp->status_pending_p = 1;
+         new_lwp->status_pending = status;
+       }
 
       /* Don't report the event.  */
       return 1;
@@ -1029,12 +1037,16 @@ attach_proc_task_lwp_callback (ptid_t ptid)
   return 0;
 }
 
+static void async_file_mark (void);
+
 /* Attach to PID.  If PID is the tgid, attach to it and all
    of its threads.  */
 
 static int
 linux_attach (unsigned long pid)
 {
+  struct process_info *proc;
+  struct thread_info *initial_thread;
   ptid_t ptid = ptid_build (pid, pid, 0);
   int err;
 
@@ -1045,17 +1057,12 @@ linux_attach (unsigned long pid)
     error ("Cannot attach to process %ld: %s",
           pid, linux_ptrace_attach_fail_reason_string (ptid, err));
 
-  linux_add_process (pid, 1);
+  proc = linux_add_process (pid, 1);
 
-  if (!non_stop)
-    {
-      struct thread_info *thread;
-
-     /* Don't ignore the initial SIGSTOP if we just attached to this
-       process.  It will be collected by wait shortly.  */
-      thread = find_thread_ptid (ptid_build (pid, pid, 0));
-      thread->last_resume_kind = resume_stop;
-    }
+  /* Don't ignore the initial SIGSTOP if we just attached to this
+     process.  It will be collected by wait shortly.  */
+  initial_thread = find_thread_ptid (ptid_build (pid, pid, 0));
+  initial_thread->last_resume_kind = resume_stop;
 
   /* We must attach to every LWP.  If /proc is mounted, use that to
      find them now.  On the one hand, the inferior may be using raw
@@ -1067,6 +1074,38 @@ linux_attach (unsigned long pid)
      that once thread_db is loaded, we'll still use it to list threads
      and associate pthread info with each LWP.  */
   linux_proc_attach_tgid_threads (pid, attach_proc_task_lwp_callback);
+
+  /* GDB will shortly read the xml target description for this
+     process, to figure out the process' architecture.  But the target
+     description is only filled in when the first process/thread in
+     the thread group reports its initial PTRACE_ATTACH SIGSTOP.  Do
+     that now, otherwise, if GDB is fast enough, it could read the
+     target description _before_ that initial stop.  */
+  if (non_stop)
+    {
+      struct lwp_info *lwp;
+      int wstat, lwpid;
+      ptid_t pid_ptid = pid_to_ptid (pid);
+
+      lwpid = linux_wait_for_event_filtered (pid_ptid, pid_ptid,
+                                            &wstat, __WALL);
+      gdb_assert (lwpid > 0);
+
+      lwp = find_lwp_pid (pid_to_ptid (lwpid));
+
+      if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGSTOP)
+       {
+         lwp->status_pending_p = 1;
+         lwp->status_pending = wstat;
+       }
+
+      initial_thread->last_resume_kind = resume_continue;
+
+      async_file_mark ();
+
+      gdb_assert (proc->tdesc != NULL);
+    }
+
   return 0;
 }
 
@@ -1486,12 +1525,6 @@ thread_still_has_status_pending_p (struct thread_info *thread)
   if (!lp->status_pending_p)
     return 0;
 
-  /* If we got a `vCont;t', but we haven't reported a stop yet, do
-     report any status pending the LWP may have.  */
-  if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
-    return 0;
-
   if (thread->last_resume_kind != resume_stop
       && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
          || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
@@ -1548,6 +1581,26 @@ thread_still_has_status_pending_p (struct thread_info *thread)
   return 1;
 }
 
+/* Returns true if LWP is resumed from the client's perspective.  */
+
+static int
+lwp_resumed (struct lwp_info *lwp)
+{
+  struct thread_info *thread = get_lwp_thread (lwp);
+
+  if (thread->last_resume_kind != resume_stop)
+    return 1;
+
+  /* Did gdb send us a `vCont;t', but we haven't reported the
+     corresponding stop to gdb yet?  If so, the thread is still
+     resumed/running from gdb's perspective.  */
+  if (thread->last_resume_kind == resume_stop
+      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+    return 1;
+
+  return 0;
+}
+
 /* Return 1 if this lwp has an interesting status pending.  */
 static int
 status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
@@ -1561,6 +1614,9 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
   if (!ptid_match (ptid_of (thread), ptid))
     return 0;
 
+  if (!lwp_resumed (lp))
+    return 0;
+
   if (lp->status_pending_p
       && !thread_still_has_status_pending_p (thread))
     {
@@ -2225,25 +2281,22 @@ linux_low_filter_event (int lwpid, int wstat)
     {
       if (debug_threads)
        debug_printf ("LLFE: %d exited.\n", lwpid);
-      if (num_lwps (pid_of (thread)) > 1)
+      /* If there is at least one more LWP, then the exit signal was
+        not the end of the debugged application and should be
+        ignored, unless GDB wants to hear about thread exits.  */
+      if (report_thread_events
+         || last_thread_of_process_p (pid_of (thread)))
        {
-
-         /* If there is at least one more LWP, then the exit signal was
-            not the end of the debugged application and should be
-            ignored.  */
-         delete_lwp (child);
-         return NULL;
+         /* Since events are serialized to GDB core, and we can't
+            report this one right now.  Leave the status pending for
+            the next time we're able to report it.  */
+         mark_lwp_dead (child, wstat);
+         return child;
        }
       else
        {
-         /* This was the last lwp in the process.  Since events are
-            serialized to GDB core, and we can't report this one
-            right now, but GDB core and the other target layers will
-            want to be notified about the exit code/signal, leave the
-            status pending for the next time we're able to report
-            it.  */
-         mark_lwp_dead (child, wstat);
-         return child;
+         delete_lwp (child);
+         return NULL;
        }
     }
 
@@ -2378,7 +2431,6 @@ resume_stopped_resumed_lwps (struct inferior_list_entry *entry)
   if (lp->stopped
       && !lp->suspended
       && !lp->status_pending_p
-      && thread->last_resume_kind != resume_stop
       && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
     {
       int step = thread->last_resume_kind == resume_step;
@@ -2587,18 +2639,6 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
 
   current_thread = event_thread;
 
-  /* Check for thread exit.  */
-  if (! WIFSTOPPED (*wstatp))
-    {
-      gdb_assert (last_thread_of_process_p (pid_of (event_thread)));
-
-      if (debug_threads)
-       debug_printf ("LWP %d is the last lwp of process.  "
-                     "Process %ld exiting.\n",
-                     pid_of (event_thread), lwpid_of (event_thread));
-      return lwpid_of (event_thread);
-    }
-
   return lwpid_of (event_thread);
 }
 
@@ -2868,8 +2908,6 @@ linux_stabilize_threads (void)
     }
 }
 
-static void async_file_mark (void);
-
 /* Convenience function that is called when the kernel reports an
    event that is not passed out to GDB.  */
 
@@ -2885,6 +2923,30 @@ ignore_event (struct target_waitstatus *ourstatus)
   return null_ptid;
 }
 
+/* Convenience function that is called when the kernel reports an exit
+   event.  This decides whether to report the event to GDB as a
+   process exit event, a thread exit event, or to suppress the
+   event.  */
+
+static ptid_t
+filter_exit_event (struct lwp_info *event_child,
+                  struct target_waitstatus *ourstatus)
+{
+  struct thread_info *thread = get_lwp_thread (event_child);
+  ptid_t ptid = ptid_of (thread);
+
+  if (!last_thread_of_process_p (pid_of (thread)))
+    {
+      if (report_thread_events)
+       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+      else
+       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
+      delete_lwp (event_child);
+    }
+  return ptid;
+}
+
 /* Wait for process, returns status.  */
 
 static ptid_t
@@ -2990,6 +3052,9 @@ linux_wait_1 (ptid_t ptid,
            }
        }
 
+      if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+       return filter_exit_event (event_child, ourstatus);
+
       return ptid_of (current_thread);
     }
 
@@ -3479,6 +3544,9 @@ linux_wait_1 (ptid_t ptid,
       debug_exit ();
     }
 
+  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+    return filter_exit_event (event_child, ourstatus);
+
   return ptid_of (current_thread);
 }
 
@@ -3879,6 +3947,8 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
   if (lwp->stopped == 0)
     return;
 
+  gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+
   fast_tp_collecting = lwp->collecting_fast_tracepoint;
 
   gdb_assert (!stabilizing_threads || fast_tp_collecting);
@@ -6128,10 +6198,10 @@ linux_read_loadmap (const char *annex, CORE_ADDR offset,
 #endif /* defined PT_GETDSBT || defined PTRACE_GETFDPIC */
 
 static void
-linux_process_qsupported (const char *query)
+linux_process_qsupported (char **features, int count)
 {
   if (the_low_target.process_qsupported != NULL)
-    the_low_target.process_qsupported (query);
+    the_low_target.process_qsupported (features, count);
 }
 
 static int
@@ -7043,7 +7113,8 @@ static struct target_ops linux_target_ops = {
   linux_mntns_unlink,
   linux_mntns_readlink,
   linux_breakpoint_kind_from_pc,
-  linux_sw_breakpoint_from_kind
+  linux_sw_breakpoint_from_kind,
+  linux_proc_tid_get_name,
 };
 
 static void
This page took 0.026877 seconds and 4 git commands to generate.