Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Luis Machado <luis.machado@arm.com>
To: Pedro Alves <pedro@palves.net>,
	gdb-patches@sourceware.org, Tom Tromey <tom@tromey.com>
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: Re: [FYI/pushed v4 08/25] Thread options & clone events (Linux GDBserver)
Date: Tue, 6 Feb 2024 11:04:26 +0000	[thread overview]
Message-ID: <bd864ea8-d7bd-4d34-a1a6-faf6c5bf3050@arm.com> (raw)
In-Reply-To: <20231113150427.477431-9-pedro@palves.net>

Hi,

On 11/13/23 15:04, Pedro Alves wrote:
> This patch teaches the Linux GDBserver backend to report clone events
> to GDB, when GDB has requested them with the GDB_THREAD_OPTION_CLONE
> thread option, via the new QThreadOptions packet.
> 
> This shuffles code in linux_process_target::handle_extended_wait
> around to a more logical order when we now have to handle and
> potentially report all of fork/vfork/clone.
> 
> Raname lwp_info::fork_relative -> lwp_info::relative as the field is
> no longer only about (v)fork.
> 
> With this, gdb.threads/stepi-over-clone.exp now cleanly passes against
> GDBserver, so remove the native-target-only requirement from that
> testcase.
> 
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19675
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27830
> Reviewed-By: Andrew Burgess <aburgess@redhat.com>
> Change-Id: I3a19bc98801ec31e5c6fdbe1ebe17df855142bb2
> ---
>  .../gdb.threads/stepi-over-clone.exp          |   6 -
>  gdbserver/linux-low.cc                        | 253 ++++++++++--------
>  gdbserver/linux-low.h                         |  47 ++--
>  3 files changed, 160 insertions(+), 146 deletions(-)
> 
> diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
> index e580f2248ac..4c496429632 100644
> --- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp
> +++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
> @@ -19,12 +19,6 @@
>  # disassembly output.  For now this is only implemented for x86-64.
>  require {istarget x86_64-*-*}
>  
> -# Test only on native targets, for now.
> -proc is_native_target {} {
> -    return [expr {[target_info gdb_protocol] == ""}]
> -}
> -require is_native_target
> -
>  standard_testfile
>  
>  if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
> diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
> index 40b6a907ad9..136a8b6c9a1 100644
> --- a/gdbserver/linux-low.cc
> +++ b/gdbserver/linux-low.cc
> @@ -491,7 +491,6 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
>    struct lwp_info *event_lwp = *orig_event_lwp;
>    int event = linux_ptrace_get_extended_event (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);
>  
> @@ -503,7 +502,6 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
>    if ((event == PTRACE_EVENT_FORK) || (event == PTRACE_EVENT_VFORK)
>        || (event == PTRACE_EVENT_CLONE))
>      {
> -      ptid_t ptid;
>        unsigned long new_pid;
>        int ret, status;
>  
> @@ -527,61 +525,65 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
>  	    warning ("wait returned unexpected status 0x%x", status);
>  	}
>  
> -      if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK)
> +      if (debug_threads)
>  	{
> -	  struct process_info *parent_proc;
> -	  struct process_info *child_proc;
> -	  struct lwp_info *child_lwp;
> -	  struct thread_info *child_thr;
> +	  debug_printf ("HEW: Got %s event from LWP %ld, new child is %ld\n",
> +			(event == PTRACE_EVENT_FORK ? "fork"
> +			 : event == PTRACE_EVENT_VFORK ? "vfork"
> +			 : event == PTRACE_EVENT_CLONE ? "clone"
> +			 : "???"),
> +			ptid_of (event_thr).lwp (),
> +			new_pid);
> +	}
> +
> +      ptid_t child_ptid = (event != PTRACE_EVENT_CLONE
> +			   ? ptid_t (new_pid, new_pid)
> +			   : ptid_t (ptid_of (event_thr).pid (), new_pid));
>  
> -	  ptid = ptid_t (new_pid, new_pid);
> +      lwp_info *child_lwp = add_lwp (child_ptid);
> +      gdb_assert (child_lwp != NULL);
> +      child_lwp->stopped = 1;
> +      if (event != PTRACE_EVENT_CLONE)
> +	child_lwp->must_set_ptrace_flags = 1;
> +      child_lwp->status_pending_p = 0;
>  
> -	  threads_debug_printf ("Got fork event from LWP %ld, "
> -				"new child is %d",
> -				ptid_of (event_thr).lwp (),
> -				ptid.pid ());
> +      thread_info *child_thr = get_lwp_thread (child_lwp);
>  
> +      /* If we're suspending all threads, leave this one suspended
> +	 too.  If the fork/clone parent is stepping over a breakpoint,
> +	 all other threads have been suspended already.  Leave the
> +	 child suspended too.  */
> +      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
> +	  || event_lwp->bp_reinsert != 0)
> +	{
> +	  threads_debug_printf ("leaving child suspended");
> +	  child_lwp->suspended = 1;
> +	}
> +
> +      if (event_lwp->bp_reinsert != 0
> +	  && supports_software_single_step ()
> +	  && event == PTRACE_EVENT_VFORK)
> +	{
> +	  /* If we leave single-step breakpoints there, child will
> +	     hit it, so uninsert single-step breakpoints from parent
> +	     (and child).  Once vfork child is done, reinsert
> +	     them back to parent.  */
> +	  uninsert_single_step_breakpoints (event_thr);
> +	}
> +
> +      if (event != PTRACE_EVENT_CLONE)
> +	{
>  	  /* Add the new process to the tables and clone the breakpoint
>  	     lists of the parent.  We need to do this even if the new process
>  	     will be detached, since we will need the process object and the
>  	     breakpoints to remove any breakpoints from memory when we
>  	     detach, and the client side will access registers.  */
> -	  child_proc = add_linux_process (new_pid, 0);
> +	  process_info *child_proc = add_linux_process (new_pid, 0);
>  	  gdb_assert (child_proc != NULL);
> -	  child_lwp = add_lwp (ptid);
> -	  gdb_assert (child_lwp != NULL);
> -	  child_lwp->stopped = 1;
> -	  child_lwp->must_set_ptrace_flags = 1;
> -	  child_lwp->status_pending_p = 0;
> -	  child_thr = get_lwp_thread (child_lwp);
> -	  child_thr->last_resume_kind = resume_stop;
> -	  child_thr->last_status.set_stopped (GDB_SIGNAL_0);
> -
> -	  /* If we're suspending all threads, leave this one suspended
> -	     too.  If the fork/clone parent is stepping over a breakpoint,
> -	     all other threads have been suspended already.  Leave the
> -	     child suspended too.  */
> -	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
> -	      || event_lwp->bp_reinsert != 0)
> -	    {
> -	      threads_debug_printf ("leaving child suspended");
> -	      child_lwp->suspended = 1;
> -	    }
>  
> -	  parent_proc = get_thread_process (event_thr);
> +	  process_info *parent_proc = get_thread_process (event_thr);
>  	  child_proc->attached = parent_proc->attached;
>  
> -	  if (event_lwp->bp_reinsert != 0
> -	      && supports_software_single_step ()
> -	      && event == PTRACE_EVENT_VFORK)
> -	    {
> -	      /* If we leave single-step breakpoints there, child will
> -		 hit it, so uninsert single-step breakpoints from parent
> -		 (and child).  Once vfork child is done, reinsert
> -		 them back to parent.  */
> -	      uninsert_single_step_breakpoints (event_thr);
> -	    }
> -
>  	  clone_all_breakpoints (child_thr, event_thr);
>  
>  	  target_desc_up tdesc = allocate_target_description ();
> @@ -590,88 +592,97 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
>  
>  	  /* Clone arch-specific process data.  */
>  	  low_new_fork (parent_proc, child_proc);
> +	}
>  
> -	  /* Save fork info in the parent thread.  */
> -	  if (event == PTRACE_EVENT_FORK)
> -	    event_lwp->waitstatus.set_forked (ptid);
> -	  else if (event == PTRACE_EVENT_VFORK)
> -	    event_lwp->waitstatus.set_vforked (ptid);
> -
> +      /* Save fork/clone info in the parent thread.  */
> +      if (event == PTRACE_EVENT_FORK)
> +	event_lwp->waitstatus.set_forked (child_ptid);
> +      else if (event == PTRACE_EVENT_VFORK)
> +	event_lwp->waitstatus.set_vforked (child_ptid);
> +      else if (event == PTRACE_EVENT_CLONE
> +	       && (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) != 0)
> +	event_lwp->waitstatus.set_thread_cloned (child_ptid);
> +
> +      if (event != PTRACE_EVENT_CLONE
> +	  || (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) != 0)
> +	{
>  	  /* The status_pending field contains bits denoting the
> -	     extended event, so when the pending event is handled,
> -	     the handler will look at lwp->waitstatus.  */
> +	     extended event, so when the pending event is handled, the
> +	     handler will look at lwp->waitstatus.  */
>  	  event_lwp->status_pending_p = 1;
>  	  event_lwp->status_pending = wstat;
>  
> -	  /* Link the threads until the parent event is passed on to
> -	     higher layers.  */
> -	  event_lwp->fork_relative = child_lwp;
> -	  child_lwp->fork_relative = event_lwp;
> -
> -	  /* If the parent thread is doing step-over with single-step
> -	     breakpoints, the list of single-step breakpoints are cloned
> -	     from the parent's.  Remove them from the child process.
> -	     In case of vfork, we'll reinsert them back once vforked
> -	     child is done.  */
> -	  if (event_lwp->bp_reinsert != 0
> -	      && supports_software_single_step ())
> -	    {
> -	      /* The child process is forked and stopped, so it is safe
> -		 to access its memory without stopping all other threads
> -		 from other processes.  */
> -	      delete_single_step_breakpoints (child_thr);
> -
> -	      gdb_assert (has_single_step_breakpoints (event_thr));
> -	      gdb_assert (!has_single_step_breakpoints (child_thr));
> -	    }
> -
> -	  /* Report the event.  */
> -	  return 0;
> +	  /* Link the threads until the parent's event is passed on to
> +	     GDB.  */
> +	  event_lwp->relative = child_lwp;
> +	  child_lwp->relative = event_lwp;
>  	}
>  
> -      threads_debug_printf
> -	("Got clone event from LWP %ld, new child is LWP %ld",
> -	 lwpid_of (event_thr), new_pid);
> -
> -      ptid = ptid_t (pid_of (event_thr), new_pid);
> -      new_lwp = add_lwp (ptid);
> -
> -      /* Either we're going to immediately resume the new thread
> -	 or leave it stopped.  resume_one_lwp is a nop if it
> -	 thinks the thread is currently running, so set this first
> -	 before calling resume_one_lwp.  */
> -      new_lwp->stopped = 1;
> +      /* If the parent thread is doing step-over with single-step
> +	 breakpoints, the list of single-step breakpoints are cloned
> +	 from the parent's.  Remove them from the child process.
> +	 In case of vfork, we'll reinsert them back once vforked
> +	 child is done.  */
> +      if (event_lwp->bp_reinsert != 0
> +	  && supports_software_single_step ())
> +	{
> +	  /* The child process is forked and stopped, so it is safe
> +	     to access its memory without stopping all other threads
> +	     from other processes.  */
> +	  delete_single_step_breakpoints (child_thr);
>  
> -      /* If we're suspending all threads, leave this one suspended
> -	 too.  If the fork/clone parent is stepping over a breakpoint,
> -	 all other threads have been suspended already.  Leave the
> -	 child suspended too.  */
> -      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
> -	  || event_lwp->bp_reinsert != 0)
> -	new_lwp->suspended = 1;
> +	  gdb_assert (has_single_step_breakpoints (event_thr));
> +	  gdb_assert (!has_single_step_breakpoints (child_thr));
> +	}
>  
>        /* Normally we will get the pending SIGSTOP.  But in some cases
>  	 we might get another signal delivered to the group first.
>  	 If we do get another signal, be sure not to lose it.  */
>        if (WSTOPSIG (status) != SIGSTOP)
>  	{
> -	  new_lwp->stop_expected = 1;
> -	  new_lwp->status_pending_p = 1;
> -	  new_lwp->status_pending = status;
> +	  child_lwp->stop_expected = 1;
> +	  child_lwp->status_pending_p = 1;
> +	  child_lwp->status_pending = status;
>  	}
> -      else if (cs.report_thread_events)
> +      else if (event == PTRACE_EVENT_CLONE && cs.report_thread_events)
>  	{
> -	  new_lwp->waitstatus.set_thread_created ();
> -	  new_lwp->status_pending_p = 1;
> -	  new_lwp->status_pending = status;
> +	  child_lwp->waitstatus.set_thread_created ();
> +	  child_lwp->status_pending_p = 1;
> +	  child_lwp->status_pending = status;
>  	}
>  
> +      if (event == PTRACE_EVENT_CLONE)
> +	{
>  #ifdef USE_THREAD_DB
> -      thread_db_notice_clone (event_thr, ptid);
> +	  thread_db_notice_clone (event_thr, child_ptid);
>  #endif
> +	}
>  
> -      /* Don't report the event.  */
> -      return 1;
> +      if (event == PTRACE_EVENT_CLONE
> +	  && (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) == 0)
> +	{
> +	  threads_debug_printf
> +	    ("not reporting clone event from LWP %ld, new child is %ld\n",
> +	     ptid_of (event_thr).lwp (),
> +	     new_pid);
> +	  return 1;
> +	}
> +
> +      /* Leave the child stopped until GDB processes the parent
> +	 event.  */
> +      child_thr->last_resume_kind = resume_stop;
> +      child_thr->last_status.set_stopped (GDB_SIGNAL_0);
> +
> +      /* Report the event.  */
> +      threads_debug_printf
> +	("reporting %s event from LWP %ld, new child is %ld\n",
> +	 (event == PTRACE_EVENT_FORK ? "fork"
> +	  : event == PTRACE_EVENT_VFORK ? "vfork"
> +	  : event == PTRACE_EVENT_CLONE ? "clone"
> +	  : "???"),
> +	 ptid_of (event_thr).lwp (),
> +	 new_pid);
> +      return 0;
>      }
>    else if (event == PTRACE_EVENT_VFORK_DONE)
>      {
> @@ -3531,15 +3542,14 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
>  
>    if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
>      {
> -      /* If the reported event is an exit, fork, vfork or exec, let
> -	 GDB know.  */
> +      /* If the reported event is an exit, fork, vfork, clone or exec,
> +	 let GDB know.  */
>  
> -      /* Break the unreported fork relationship chain.  */
> -      if (event_child->waitstatus.kind () == TARGET_WAITKIND_FORKED
> -	  || event_child->waitstatus.kind () == TARGET_WAITKIND_VFORKED)
> +      /* Break the unreported fork/vfork/clone relationship chain.  */
> +      if (is_new_child_status (event_child->waitstatus.kind ()))
>  	{
> -	  event_child->fork_relative->fork_relative = NULL;
> -	  event_child->fork_relative = NULL;
> +	  event_child->relative->relative = NULL;
> +	  event_child->relative = NULL;
>  	}
>  
>        *ourstatus = event_child->waitstatus;
> @@ -4272,15 +4282,14 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
>  	      continue;
>  	    }
>  
> -	  /* Don't let wildcard resumes resume fork children that GDB
> -	     does not yet know are new fork children.  */
> -	  if (lwp->fork_relative != NULL)
> +	  /* Don't let wildcard resumes resume fork/vfork/clone
> +	     children that GDB does not yet know are new children.  */
> +	  if (lwp->relative != NULL)
>  	    {
> -	      struct lwp_info *rel = lwp->fork_relative;
> +	      struct lwp_info *rel = lwp->relative;
>  
>  	      if (rel->status_pending_p
> -		  && (rel->waitstatus.kind () == TARGET_WAITKIND_FORKED
> -		      || rel->waitstatus.kind () == TARGET_WAITKIND_VFORKED))
> +		  && is_new_child_status (rel->waitstatus.kind ()))
>  		{
>  		  threads_debug_printf
>  		    ("not resuming LWP %ld: has queued stop reply",
> @@ -5907,6 +5916,14 @@ linux_process_target::supports_vfork_events ()
>    return true;
>  }
>  
> +/* Return the set of supported thread options.  */
> +
> +gdb_thread_options
> +linux_process_target::supported_thread_options ()
> +{
> +  return GDB_THREAD_OPTION_CLONE;
> +}
> +
>  /* Check if exec events are supported.  */
>  
>  bool
> diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h
> index f7cedf6706b..94093dd4ed8 100644
> --- a/gdbserver/linux-low.h
> +++ b/gdbserver/linux-low.h
> @@ -234,6 +234,8 @@ class linux_process_target : public process_stratum_target
>  
>    bool supports_vfork_events () override;
>  
> +  gdb_thread_options supported_thread_options () override;
> +
>    bool supports_exec_events () override;
>  
>    void handle_new_gdb_connection () override;
> @@ -732,48 +734,47 @@ struct pending_signal
>  
>  struct lwp_info
>  {
> -  /* If this LWP is a fork child that wasn't reported to GDB yet, return
> -     its parent, else nullptr.  */
> +  /* If this LWP is a fork/vfork/clone child that wasn't reported to
> +     GDB yet, return its parent, else nullptr.  */
>    lwp_info *pending_parent () const
>    {
> -    if (this->fork_relative == nullptr)
> +    if (this->relative == nullptr)
>        return nullptr;
>  
> -    gdb_assert (this->fork_relative->fork_relative == this);
> +    gdb_assert (this->relative->relative == this);
>  
> -    /* In a fork parent/child relationship, the parent has a status pending and
> +    /* In a parent/child relationship, the parent has a status pending and
>         the child does not, and a thread can only be in one such relationship
>         at most.  So we can recognize who is the parent based on which one has
>         a pending status.  */
>      gdb_assert (!!this->status_pending_p
> -		!= !!this->fork_relative->status_pending_p);
> +		!= !!this->relative->status_pending_p);
>  
> -    if (!this->fork_relative->status_pending_p)
> +    if (!this->relative->status_pending_p)
>        return nullptr;
>  
>      const target_waitstatus &ws
> -      = this->fork_relative->waitstatus;
> +      = this->relative->waitstatus;
>      gdb_assert (ws.kind () == TARGET_WAITKIND_FORKED
>  		|| ws.kind () == TARGET_WAITKIND_VFORKED);
>  
> -    return this->fork_relative;
> -  }
> +    return this->relative; }
>  
> -  /* If this LWP is the parent of a fork child we haven't reported to GDB yet,
> -     return that child, else nullptr.  */
> +  /* If this LWP is the parent of a fork/vfork/clone child we haven't
> +     reported to GDB yet, return that child, else nullptr.  */
>    lwp_info *pending_child () const
>    {
> -    if (this->fork_relative == nullptr)
> +    if (this->relative == nullptr)
>        return nullptr;
>  
> -    gdb_assert (this->fork_relative->fork_relative == this);
> +    gdb_assert (this->relative->relative == this);
>  
> -    /* In a fork parent/child relationship, the parent has a status pending and
> +    /* In a parent/child relationship, the parent has a status pending and
>         the child does not, and a thread can only be in one such relationship
>         at most.  So we can recognize who is the parent based on which one has
>         a pending status.  */
>      gdb_assert (!!this->status_pending_p
> -		!= !!this->fork_relative->status_pending_p);
> +		!= !!this->relative->status_pending_p);
>  
>      if (!this->status_pending_p)
>        return nullptr;
> @@ -782,7 +783,7 @@ struct lwp_info
>      gdb_assert (ws.kind () == TARGET_WAITKIND_FORKED
>  		|| ws.kind () == TARGET_WAITKIND_VFORKED);
>  
> -    return this->fork_relative;
> +    return this->relative;
>    }
>  
>    /* Backlink to the parent object.  */
> @@ -820,11 +821,13 @@ struct lwp_info
>       information or exit status until it can be reported to GDB.  */
>    struct target_waitstatus waitstatus;
>  
> -  /* A pointer to the fork child/parent relative.  Valid only while
> -     the parent fork event is not reported to higher layers.  Used to
> -     avoid wildcard vCont actions resuming a fork child before GDB is
> -     notified about the parent's fork event.  */
> -  struct lwp_info *fork_relative = nullptr;
> +  /* A pointer to the fork/vfork/clone child/parent relative (like
> +     people, LWPs have relatives).  Valid only while the parent
> +     fork/vfork/clone event is not reported to higher layers.  Used to
> +     avoid wildcard vCont actions resuming a fork/vfork/clone child
> +     before GDB is notified about the parent's fork/vfork/clone
> +     event.  */
> +  struct lwp_info *relative = nullptr;
>  
>    /* When stopped is set, this is where the lwp last stopped, with
>       decr_pc_after_break already accounted for.  If the LWP is

Tromey had pointed out, on IRC, gdbserver was crashing when stepping over a fork on aarch64. I went to investigate it and noticed the testsuite
run for --target_board=native-gdbserver was really bad in terms of FAIL's (over 700). This is Ubuntu 20.04.

I bisected the FAIL's for at least one testcase (gdb.threads/next-fork-other-thread.exp) to this particular commit. But the series is large, so it could
potentially be something else in the series.

I haven't fully investigated the crashes yet, but thought I'd mention it for the record and to see if any bells rang.

  reply	other threads:[~2024-02-06 11:05 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-13 15:04 [FYI/pushed v4 00/25] Step over thread clone and thread exit Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 01/25] Add "maint info linux-lwps" command Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 02/25] gdb/linux: Delete all other LWPs immediately on ptrace exec event Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 03/25] Step over clone syscall w/ breakpoint, TARGET_WAITKIND_THREAD_CLONED Pedro Alves
2023-11-14 12:55   ` Guinevere Larsen
2023-11-14 13:26     ` Pedro Alves
2023-11-14 16:29       ` Guinevere Larsen
2023-11-14 16:44         ` Luis Machado
2023-11-14 13:28     ` Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 04/25] Support clone events in the remote protocol Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 05/25] Avoid duplicate QThreadEvents packets Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 06/25] Thread options & clone events (core + remote) Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 07/25] Thread options & clone events (native Linux) Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 08/25] Thread options & clone events (Linux GDBserver) Pedro Alves
2024-02-06 11:04   ` Luis Machado [this message]
2024-02-06 14:57     ` Tom Tromey
2024-02-06 15:12       ` Luis Machado
2024-02-07  8:59       ` Luis Machado
2024-02-07 15:43         ` Tom Tromey
2024-02-07 17:10           ` Simon Marchi
2024-02-07 18:05             ` Luis Machado
2024-02-07 18:18               ` Tom Tromey
2024-02-07 18:56                 ` Pedro Alves
2024-02-07 20:11                   ` Pedro Alves
2024-02-08  8:57                     ` Luis Machado
2024-02-08 10:53                       ` Pedro Alves
2024-02-08 11:47                         ` Luis Machado
2024-02-08 14:58                     ` Tom Tromey
2024-02-07 18:06             ` Tom Tromey
2023-11-13 15:04 ` [FYI/pushed v4 09/25] gdbserver: Hide and don't detach pending clone children Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 10/25] Remove gdb/19675 kfails (displaced stepping + clone) Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 11/25] all-stop/synchronous RSP support thread-exit events Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 12/25] gdbserver/linux-low.cc: Ignore event_ptid if TARGET_WAITKIND_IGNORE Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 13/25] Move deleting thread on TARGET_WAITKIND_THREAD_EXITED to core Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 14/25] Introduce GDB_THREAD_OPTION_EXIT thread option, fix step-over-thread-exit Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 15/25] Implement GDB_THREAD_OPTION_EXIT support for Linux GDBserver Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 16/25] Implement GDB_THREAD_OPTION_EXIT support for native Linux Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 17/25] gdb: clear step over information on thread exit (PR gdb/27338) Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 18/25] stop_all_threads: (re-)enable async before waiting for stops Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 19/25] gdbserver: Queue no-resumed event after thread exit Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 20/25] Don't resume new threads if scheduler-locking is in effect Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 21/25] Report thread exit event for leader if reporting thread exit events Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 22/25] gdb/testsuite/lib/my-syscalls.S: Refactor new SYSCALL macro Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 23/25] Testcases for stepping over thread exit syscall (PR gdb/27338) Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 24/25] Document remote clone events, and QThreadOptions packet Pedro Alves
2023-11-13 15:04 ` [FYI/pushed v4 25/25] Cancel execution command on thread exit, when stepping, nexting, etc Pedro Alves
2023-11-13 19:28 ` [FYI/pushed v4 00/25] Step over thread clone and thread exit Tom de Vries
2023-11-14 10:51   ` Pedro Alves
2023-11-14 13:39     ` Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bd864ea8-d7bd-4d34-a1a6-faf6c5bf3050@arm.com \
    --to=luis.machado@arm.com \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=pedro@palves.net \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox