[PATCH] [remote/gdbserver] Don't lose signals when reconnecting.

Pedro Alves palves@redhat.com
Wed Jan 8 20:37:00 GMT 2014


On 11/06/2013 12:28 PM, Yao Qi wrote:
> On 11/06/2013 08:12 PM, Pedro Alves wrote:
>> We'll still lose an asynchronous SIGTRAP.  That is, e.g., if the
>> program was stopped due to a '$kill -SIGTRAP $pid' from the shell.
>> On Linux, we can tell whether a signal was sent by the kernel or
>> by the program by looking at siginfo->si_code (SI_USER, SI_KERNEL,
>> etc., see /usr/include/bits/siginfo.h).
>>
>> Note that since most stubs out there, including GDBserver, are
>> always reporting GDB_SIGNAL_TRAP on initial connection (instead of
>> GDB_SIGNAL_0), GDB will have to keep silently swallowing
>> GDB_SIGNAL_TRAP.  We'd also need a new target feature to get
>> around that.  Given that "all-stop on top of non-stop" wouldn't
>> have that problem (as stubs report GDB_SIGNAL_0 for stopped threads,
>> not GDB_SIGNAL_TRAP), I'm not bothering with that.
> 
> That is clear to me now, thanks.

Thanks.  I've now pushed the patch and ...

>>>>>> @@ -2544,13 +2635,15 @@ handle_status (char *own_buf)
>>>>>>     /* GDB is connected, don't forward events to the target anymore.  */
>>>>>>     for_each_inferior (&all_processes, gdb_reattached_process);
>>>>>>
>>>>>> +  discard_queued_stop_replies (-1);
>>>>>> +  for_each_inferior (&all_threads, clear_pending_status_callback);
>>>>>> +
>>>>>>     /* In non-stop mode, we must send a stop reply for each stopped
>>>>>>        thread.  In all-stop mode, just send one for the first stopped
>>>>>>        thread we find.  */
>>>>>>
>>>>>>     if (non_stop)
>>>>>>       {
>>>>>> -      discard_queued_stop_replies (-1);
>>>>
>>>> I'd like to figure out the reason call discard_queued_stop_replies in
>>>> all-stop mode.  We want to handle the case that all-stop GDB connects to
>>>> a non-stop GDBserver, and discard all previous stop replies,
>> Yes, that.  Perhaps even better would be to discard them immediately
>> when the previous GDB disconnects.  We don't queue stop replies if
>> GDB isn't connected (disconnected tracing) anyway.
>>
> 
> Yes, I agree.  I have no other comments on this patch.

... pushed the following patch on top.

-----------
Subject: [PATCH] GDBserver: Discard previous queued events when GDB
 disconnects.

... not when a new GDB connection sends the status packet ('?').
Mainly just a cleanup/simplification, as GDB always sends '?' first.

Tested on x86_64 Fedora 17.

2014-01-08  Pedro Alves  <palves@redhat.com>

	* server.c (handle_status): Don't discard previous queued stop
	replies or thread's pending status here.
	(main) <disconnection>: Do it here instead.
---
 gdb/gdbserver/ChangeLog | 6 ++++++
 gdb/gdbserver/server.c  | 9 ++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index bf874a1..adba6f6 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,11 @@
 2014-01-08  Pedro Alves  <palves@redhat.com>
 
+	* server.c (handle_status): Don't discard previous queued stop
+	replies or thread's pending status here.
+	(main) <disconnection>: Do it here instead.
+
+2014-01-08  Pedro Alves  <palves@redhat.com>
+
 	* gdbthread.h (struct thread_info) <status_pending_p>: New field.
 	* server.c (visit_actioned_threads, handle_pending_status): New
 	function.
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 5e80075..c9d9eec 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2635,9 +2635,6 @@ handle_status (char *own_buf)
   /* GDB is connected, don't forward events to the target anymore.  */
   for_each_inferior (&all_processes, gdb_reattached_process);
 
-  discard_queued_stop_replies (-1);
-  for_each_inferior (&all_threads, clear_pending_status_callback);
-
   /* In non-stop mode, we must send a stop reply for each stopped
      thread.  In all-stop mode, just send one for the first stopped
      thread we find.  */
@@ -3140,6 +3137,12 @@ main (int argc, char *argv[])
 	       "Remote side has terminated connection.  "
 	       "GDBserver will reopen the connection.\n");
 
+      /* Get rid of any pending statuses.  An eventual reconnection
+	 (by the same GDB instance or another) will refresh all its
+	 state from scratch.  */
+      discard_queued_stop_replies (-1);
+      for_each_inferior (&all_threads, clear_pending_status_callback);
+
       if (tracing)
 	{
 	  if (disconnected_tracing)
-- 
1.7.11.7



-- 
Pedro Alves



More information about the Gdb-patches mailing list