[16/18] gdbserver/linux: Always wake up event loop after resume

Message ID 1444836486-25679-17-git-send-email-palves@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Oct. 14, 2015, 3:28 p.m. UTC
  Running killed-outside.exp in with "maint set target-non-stop on"
hangs currently.  This test has the inferior process die with a
SIGKILL while stopped.  gdbserver gets a SIGCHLD and reacts by
retrieveing the SIGKILL events out of waitpid.  But because the
process is not resumed from GDB's perspective, the event is left
pending.  When GDB resumes the process afterwards, the process is not
really resumed because it already has the event pending.  But nothing
wakes up the event loop to consume the event.

Handle this in the same way nat/linux-nat.c:linux_nat_resume handles
this.

gdb/gdbserver/ChangeLog:
2015-10-14  Pedro Alves  <palves@redhat.com>

	* linux-low.c (linux_resume): Wake up the event loop before
	returning.
---
 gdb/gdbserver/linux-low.c | 5 +++++
 1 file changed, 5 insertions(+)
  

Comments

Yao Qi Oct. 26, 2015, 2:32 p.m. UTC | #1
Pedro Alves <palves@redhat.com> writes:

> Handle this in the same way nat/linux-nat.c:linux_nat_resume handles
> this.

Nit, it is linux-nat.c instead of nat/linux-nat.c.  In linux_nat_resume,
async_file_mark is guarded by lwp_status_pending_p (lp), so we need to
check whether there is an event pending in GDBserver too.
  
Pedro Alves Nov. 25, 2015, 3:31 p.m. UTC | #2
On 10/26/2015 02:32 PM, Yao Qi wrote:
> Pedro Alves <palves@redhat.com> writes:
> 
>> Handle this in the same way nat/linux-nat.c:linux_nat_resume handles
>> this.
> 
> Nit, it is linux-nat.c instead of nat/linux-nat.c.  In linux_nat_resume,
> async_file_mark is guarded by lwp_status_pending_p (lp), so we need to
> check whether there is an event pending in GDBserver too.

I don't think we can just check whether there is an event pending
in the current thread -- the pending event may be in any
other thread that is now resumed from the client's perspective.
As we'd have to walk all threads anyway, seems simplest to just
unconditionally mark the event loop and let linux_wait & friends
handle that.

On the native side, we may have a latent bug and things work anyhow
because something else always wakes up the event loop once.  (E.g.,
nowadays target_async always marks infrun's event source.)

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 73abe5c..c464207 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4773,6 +4773,11 @@  linux_resume (struct thread_resume *resume_info, size_t n)
       debug_printf ("linux_resume done\n");
       debug_exit ();
     }
+
+  /* We may have events that were pending that can/should be sent to
+     the client now.  Trigger a linux_wait call.  */
+  if (target_is_async_p ())
+    async_file_mark ();
 }
 
 /* This function is called once per thread.  We check the thread's