This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] [remote/gdbserver] Don't lose signals when reconnecting.
- From: Pedro Alves <palves at redhat dot com>
- To: Yao Qi <yao at codesourcery dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Wed, 08 Jan 2014 20:37:51 +0000
- Subject: Re: [PATCH] [remote/gdbserver] Don't lose signals when reconnecting.
- Authentication-results: sourceware.org; auth=none
- References: <1383591233-20940-1-git-send-email-palves at redhat dot com> <5279E470 dot 7060603 at codesourcery dot com> <527A3227 dot 2080308 at redhat dot com> <527A35F4 dot 6090605 at codesourcery dot com>
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