Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Antoine Tremblay <antoine.tremblay@ericsson.com>
To: Pedro Alves <palves@redhat.com>
Cc: Antoine Tremblay <antoine.tremblay@ericsson.com>,
	<gdb-patches@sourceware.org>
Subject: Re: [PATCH v3] Fix failure to detach if threads exit while detaching on linux
Date: Fri, 03 Jun 2016 19:32:00 -0000	[thread overview]
Message-ID: <wwokoa7ijcfs.fsf@ericsson.com> (raw)
In-Reply-To: <d0336117-d7fc-3e7d-6508-c5f4cd04da47@redhat.com>


Pedro Alves writes:

> On 06/03/2016 05:43 PM, Antoine Tremblay wrote:
>> Updated patch...
>> 
>> Thanks for looking at this!
>
> The test hangs waiting for gdbserver to exit, because gdbserver
> doesn't exit.  :-)
>
> So the extra testing actually found a bug.  Good, see?  :-)
>

Haha wow indeed :)

> gdbserver is stuck in linux_join:
>
> (gdb) bt
> #0  0x00007f31e08af0da in __GI___waitpid (pid=13862, stat_loc=0x7fffcdf15f28, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
> #1  0x000000000043bc53 in my_waitpid (pid=13862, status=0x7fffcdf15f28, flags=0) at /home/pedro/gdb/mygit/src/gdb/gdbserver/../nat/linux-waitpid.c:88
> #2  0x000000000042e0d0 in linux_join (pid=13862) at /home/pedro/gdb/mygit/src/gdb/gdbserver/linux-low.c:1603
> #3  0x0000000000414145 in process_serial_event () at /home/pedro/gdb/mygit/src/gdb/gdbserver/server.c:4000
> #4  0x0000000000414fb7 in handle_serial_event (err=0, client_data=0x0) at /home/pedro/gdb/mygit/src/gdb/gdbserver/server.c:4347
> #5  0x000000000041bf42 in handle_file_event (event_file_desc=4) at /home/pedro/gdb/mygit/src/gdb/gdbserver/event-loop.c:428
> #6  0x000000000041b66e in process_event () at /home/pedro/gdb/mygit/src/gdb/gdbserver/event-loop.c:184
> #7  0x000000000041c4b6 in start_event_loop () at /home/pedro/gdb/mygit/src/gdb/gdbserver/event-loop.c:547
> #8  0x0000000000413896 in captured_main (argc=4, argv=0x7fffcdf16358) at /home/pedro/gdb/mygit/src/gdb/gdbserver/server.c:3719
> #9  0x0000000000413abf in main (argc=4, argv=0x7fffcdf16358) at /home/pedro/gdb/mygit/src/gdb/gdbserver/server.c:3804
> (gdb)
>
> Running the test manually, I can reproduce it.  In this one run, 
> gdbserver is waiting for pid 32650 to exit.  And that process'es
> status is:
>
>  $ cat  /proc/32650/status 
>  Name:   detach-gone-thr
>  State:  Z (zombie)
>  Tgid:   32650
>  Ngid:   0
>  Pid:    32650
>  PPid:   32642
>  TracerPid:      0
>  ...
>  Threads:        256
>
> So why isn't gdbserver's inferior process exiting and reporting
> a status to gdbserver, which is the inferior process'es parent?
>
> Notice TracerPid == 0.  That means gdbserver successfully detached
> from that lwp.
>
> However, seems like gdbserver didn't manage to detach from
> any of the other threads:
>
> $ grep -h State /proc/32650/task/*/status | sort | uniq -c
>     256 State:  Z (zombie)
>
> $ grep -h Tracer /proc/32650/task/*/status | sort | uniq -c
>       1 TracerPid:      0
>     255 TracerPid:      32642
>
> 32642 is gdbserver, which again, is also 32650's parent.
>
> gdbserver is detaching from the leader thread first,
> while gdb isn't.  So I thought I'd try to make gdbserver
> detach from the non-leader lwps first.  Doesn't make a
> difference.
>
> Under ptrace, the leader thread doesn't report an exit to the
> ptracer until all the children are reaped.  So I thought I'd try
> to make gdbserver collect the exit status of each zombie lwp,
> since it's still supposedly attached to them.
> And there you go, that works.  See hacky patch on top of yours below.
> The important bit is this:
>
> -    if (!check_ptrace_stopped_lwp_gone (lwp))
> -      error (_("Can't detach %s: %s"),
> -	     target_pid_to_str (ptid_of (thread)),
> -	     strerror (errno));
> +    {
> +      int ret, status;
> +
> +      if (!check_ptrace_stopped_lwp_gone (lwp))
> +	error (_("Can't detach %s: %s"),
> +	       target_pid_to_str (ptid_of (thread)),
> +	       strerror (errno));
> +
> +      ret = waitpid (lwpid, &status, __WALL);
> +    }
>  
> I have to go right now, but I'll clean this up once I have a chance.
>

I have to go too, I'll pick this up Monday, I need some time to figure
this out :)

Thanks again!
Antoine

> From 2895f87d0f59de37dcbd3f0f3cd281e26303bb7d Mon Sep 17 00:00:00 2001
> From: Pedro Alves <palves@redhat.com>
> Date: Fri, 3 Jun 2016 20:09:14 +0100
> Subject: [PATCH] fix hang
>
> ---
>  gdb/gdbserver/linux-low.c                        | 52 +++++++++++++++++-------
>  gdb/testsuite/gdb.threads/detach-gone-thread.exp |  1 +
>  2 files changed, 39 insertions(+), 14 deletions(-)
>
> diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
> index 5f02dab..aad38a4 100644
> --- a/gdb/gdbserver/linux-low.c
> +++ b/gdb/gdbserver/linux-low.c
> @@ -1480,16 +1480,12 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp)
>    return 0;
>  }
>  
> -static int
> -linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
> +static void
> +linux_detach_one_lwp (struct lwp_info *lwp)
>  {
> -  struct thread_info *thread = (struct thread_info *) entry;
> -  struct lwp_info *lwp = get_thread_lwp (thread);
> -  int pid = * (int *) args;
> +  struct thread_info *thread = get_lwp_thread (lwp);
>    int sig;
> -
> -  if (ptid_get_pid (entry->id) != pid)
> -    return 0;
> +  int lwpid;
>  
>    /* If there is a pending SIGSTOP, get rid of it.  */
>    if (lwp->stop_expected)
> @@ -1511,14 +1507,38 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
>    /* Finally, let it resume.  */
>    if (the_low_target.prepare_to_resume != NULL)
>      the_low_target.prepare_to_resume (lwp);
> -  if (ptrace (PTRACE_DETACH, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
> +  lwpid = lwpid_of (thread);
> +  if (ptrace (PTRACE_DETACH, lwpid, (PTRACE_TYPE_ARG3) 0,
>  	      (PTRACE_TYPE_ARG4) (long) sig) < 0)
> -    if (!check_ptrace_stopped_lwp_gone (lwp))
> -      error (_("Can't detach %s: %s"),
> -	     target_pid_to_str (ptid_of (thread)),
> -	     strerror (errno));
> +    {
> +      int ret, status;
> +
> +      if (!check_ptrace_stopped_lwp_gone (lwp))
> +	error (_("Can't detach %s: %s"),
> +	       target_pid_to_str (ptid_of (thread)),
> +	       strerror (errno));
> +
> +      ret = waitpid (lwpid, &status, __WALL);
> +    }
>  
>    delete_lwp (lwp);
> +}
> +
> +static int
> +linux_detach_lwp_callback (struct inferior_list_entry *entry, void *args)
> +{
> +  struct thread_info *thread = (struct thread_info *) entry;
> +  struct lwp_info *lwp = get_thread_lwp (thread);
> +  int pid = * (int *) args;
> +  int lwpid = lwpid_of (thread);
> +
> +  if (ptid_get_pid (entry->id) != pid)
> +    return 0;
> +
> +  // if (ptid_get_pid (entry->id) == lwpid)
> +  //  return 0;
> +
> +  linux_detach_one_lwp (lwp);
>    return 0;
>  }
>  
> @@ -1549,7 +1569,11 @@ linux_detach (int pid)
>    /* Stabilize threads (move out of jump pads).  */
>    stabilize_threads ();
>  
> -  find_inferior (&all_threads, linux_detach_one_lwp, &pid);
> +  /* Detach from the children first.  */
> +  find_inferior (&all_threads, linux_detach_lwp_callback, &pid);
> +
> +  //  struct lwp_info *lwp = find_lwp_pid (pid_to_ptid (pid));
> +  // linux_detach_one_lwp (lwp);
>  
>    the_target->mourn (process);
>  
> diff --git a/gdb/testsuite/gdb.threads/detach-gone-thread.exp b/gdb/testsuite/gdb.threads/detach-gone-thread.exp
> index b8caf18..1780aeb 100644
> --- a/gdb/testsuite/gdb.threads/detach-gone-thread.exp
> +++ b/gdb/testsuite/gdb.threads/detach-gone-thread.exp
> @@ -31,6 +31,7 @@ proc test_server_exit {} {
>  	return
>      }
>  
> +    set test "server exits"
>      gdb_expect {
>  	-i $server_spawn_id
>  	eof {


      reply	other threads:[~2016-06-03 19:32 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-02 14:16 [PATCH] " Antoine Tremblay
2016-06-03 11:43 ` Pedro Alves
2016-06-03 11:55   ` Antoine Tremblay
2016-06-03 12:05     ` Pedro Alves
2016-06-03 14:49       ` [PATCH v2] " Antoine Tremblay
2016-06-03 15:16         ` Pedro Alves
2016-06-03 15:32           ` Antoine Tremblay
2016-06-03 15:45             ` Pedro Alves
2016-06-03 15:59               ` Antoine Tremblay
2016-06-03 16:21                 ` Pedro Alves
2016-06-03 16:43                   ` [PATCH v3] " Antoine Tremblay
2016-06-03 19:15                     ` Pedro Alves
2016-06-03 19:32                       ` Antoine Tremblay [this message]

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=wwokoa7ijcfs.fsf@ericsson.com \
    --to=antoine.tremblay@ericsson.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.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