public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/globalstate: Support successive notifications.
@ 2016-07-19 20:31 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2016-07-19 20:31 UTC (permalink / raw)
To: archer-commits
The branch, scox/globalstate has been updated
via 4739424d4a0d9ee8505b47434df6565c5271c353 (commit)
from d7a6805f1d4956568ca5f2fb995bb84d522f97ba (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 4739424d4a0d9ee8505b47434df6565c5271c353
Author: Stan Cox <scox@redhat.com>
Date: Tue Jul 19 16:30:09 2016 -0400
Support successive notifications.
* server.c (get_packet_type): Add Hg,m,M,g,G
(is_waiter): New.
(setup_multiplexing): Send shadow client notification when
vStopped received.
(notify_clients): Add have_first_notify to indicate if this is an
initial notification. Handle first and successive notify case.
(handle_monitor_command): Display thread info for client state
* server.h (new_general_thread): Intended for synchronizing
multiple client threads.
(in_buffer): Renamed notify_buffer.
* gdb.server/multi-client.exp (testpath5): Added multi-threads.c test.
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/ChangeLog | 13 ++
gdb/gdbserver/notif.c | 3 +-
gdb/gdbserver/server.c | 209 +++++++++++++++++--------
gdb/gdbserver/server.h | 9 +-
gdb/testsuite/ChangeLog | 4 +
gdb/testsuite/gdb.server/multi-client.exp | 235 ++++++++++++++++++++++-------
6 files changed, 349 insertions(+), 124 deletions(-)
First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 231b91e..1f4425d 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,16 @@
+2016-07-19 Stan Cox <scox@redhat.com>
+
+ * server.c (get_packet_type): Add Hg,m,M,g,G
+ (is_waiter): New.
+ (setup_multiplexing): Send shadow client notification when
+ vStopped received.
+ (notify_clients): Add have_first_notify to indicate if this is an
+ initial notification. Handle first and successive notify case.
+ (handle_monitor_command): Display thread info for client state
+ * server.h (new_general_thread): Intended for synchronizing
+ multiple client threads.
+ (in_buffer): Renamed notify_buffer.
+
2016-06-08 Stan Cox <scox@redhat.com>
* server.c (add_client_by_pid) Check all/non stop mode equivalence.
diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c
index 98e1b4d..8a7900b 100644
--- a/gdb/gdbserver/notif.c
+++ b/gdb/gdbserver/notif.c
@@ -67,6 +67,7 @@ notif_write_event (struct notif_server *notif, char *own_buf)
= QUEUE_peek (notif_event_p, notif->queue);
notif->write (event, own_buf);
+ notify_clients (own_buf, 0);
}
else
write_ok (own_buf);
@@ -150,7 +151,7 @@ notif_push (struct notif_server *np, struct notif_event *new_event)
p += strlen (p);
np->write (new_event, p);
- if (notify_clients (buf))
+ if (notify_clients (buf, 1))
putpkt_notif (buf);
}
}
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index b0206c6..1d5f326 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -85,11 +85,11 @@ static struct client_states client_states;
static void handle_status (char *);
-enum pending_types {none_pending, pending_waitee, pending_cont_waiter, pending_step_waiter, pending_stop};
-char *pending_types_str[] = {"not-waiting","waitee","waiter","step-waiter","stop", "notifier"};
+enum pending_types {none_pending, pending_waitee, pending_cont_waiter, pending_step_waiter};
+char *pending_types_str[] = {"not-waiting","waitee","waiter","step-waiter"};
enum nonstop_pending_types {no_notifier_pending, pending_notifier, pending_notified};
char *nonstop_pending_types_str[] = {"", "notifier", "notified"};
-char *packet_types_str[] = {"other", "vContc", "vConts","vContt","vRun", "vAttach"};
+char *packet_types_str[] = {"other", "vContc", "vConts","vContt","vRun", "vAttach", "Hg", "g_or_m", "vStopped"};
char *waitkind_str[] = {"exited", "stopped", "signalled", "loaded", "forked", "vforked", "execed", "vfork-done", "syscall-entry", "syscall-exit", "spurious", "ignore", "no-history", "not-resumed", "thread-created", "thread-exited", ""};
@@ -153,7 +153,7 @@ set_client_state (gdb_fildes_t fd)
cs->packet_type = other_packet;
cs->last_packet_type = other_packet;
cs->pending = none_pending;
- cs->in_buffer_ = NULL;
+ cs->notify_buffer_ = NULL;
cs->own_buffer_ = xmalloc (PBUFSIZ + 1);
cs->client_breakpoints = NULL;
client_states.current_cs = cs;
@@ -260,8 +260,8 @@ static void free_client_state (client_state *cs)
if (csi == NULL)
XDELETE (cs->ss);
- if (cs->in_buffer_)
- xfree (cs->in_buffer_);
+ if (cs->notify_buffer_)
+ xfree (cs->notify_buffer_);
xfree (cs->own_buffer_);
XDELETE (cs);
}
@@ -329,7 +329,7 @@ add_client_by_pid (int pid)
{
if (cs != matched_cs && matched_cs->ss->general_thread_.pid == pid)
{
- // Do clients all/non stop modes match?
+ /* Do clients all/non stop modes match? */
if (cs->non_stop_ ^ matched_cs->non_stop_)
return -1;
/* reuse the matched server state */
@@ -429,8 +429,8 @@ get_packet_type (client_state *cs)
{
char own_packet;
- if (in_buffer)
- own_packet = in_buffer[0];
+ if (own_buffer)
+ own_packet = own_buffer[0];
else
return other_packet;
/* We have already categorized the packet type */
@@ -441,22 +441,44 @@ get_packet_type (client_state *cs)
switch (own_packet)
{
case 'v':
- if ((strncmp (in_buffer, "vCont;c", 7) == 0))
+ if ((strncmp (own_buffer, "vCont;c", 7) == 0))
return vContc;
- else if ((strncmp (in_buffer, "vCont;r", 7) == 0)
- || (strncmp (in_buffer, "vCont;s", 7) == 0))
+ else if ((strncmp (own_buffer, "vCont;r", 7) == 0)
+ || (strncmp (own_buffer, "vCont;s", 7) == 0))
return vConts;
- else if ((strncmp (in_buffer, "vCont;t", 7) == 0))
+ else if ((strncmp (own_buffer, "vCont;t", 7) == 0))
return vContt;
- else if (strncmp (in_buffer, "vRun", 4) == 0)
+ else if (strncmp (own_buffer, "vRun", 4) == 0)
return vRun;
- else if (strncmp (in_buffer, "vAttach", 4) == 0)
+ else if (strncmp (own_buffer, "vAttach", 4) == 0)
return vAttach;
- default:
- return other_packet;
+ else if (strncmp (own_buffer, "vStopped", 4) == 0)
+ return vStopped;
+ break;
+ case 'H':
+ if (own_buffer[1] == 'g')
+ {
+ client_states.current_cs->new_general_thread = read_ptid (&own_buffer[2], NULL);
+ return Hg;
+ }
+ case 'm':
+ case 'M':
+ case 'g':
+ case 'G':
+ return g_or_m;
};
+ return other_packet;
+}
+
+static int is_waiter (client_state *cs)
+{
+ return ((cs->packet_type == vContc
+ || cs->packet_type == vConts)
+ && (cs->pending == pending_cont_waiter
+ || cs->pending == pending_step_waiter));
}
+
static int queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg);
/* Belatedly reply to client CS, which is waiting on a packet reply. */
@@ -537,7 +559,7 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
find_inferior (&all_threads, queue_stop_reply_callback, NULL);
notif_write_event (¬if_stop, notif_buf);
out_buf = alloca (strlen (notif_buf) + 8);
- // TODO Use Defined notif constant
+ /* TODO Use Defined notif constant */
strcpy (out_buf, "Stop:");
strcat (out_buf, notif_buf);
if (debug_threads)
@@ -550,7 +572,6 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
}
case vRun:
{
- /* reply to vRun with an OK */
strcpy (own_buffer, "OK");
putpkt (own_buffer);
break;
@@ -564,18 +585,18 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
static void
-analyze_group (client_state *current_cs, int *have_nonwaiter)
+analyze_group (client_state *current_cs, int *have_waitee)
{
client_state *csi;
- *have_nonwaiter = 0;
+ *have_waitee = 0;
for (csi = client_states.first->next; csi != NULL; csi = csi->next)
{
if (attached_to_same_proc (current_cs, csi))
{
if (csi->pending == pending_waitee || csi->pending == none_pending)
- *have_nonwaiter += 1;
+ *have_waitee += 1;
}
}
}
@@ -613,6 +634,17 @@ setup_multiplexing (client_state *current_cs)
if (current_cs->packet_type == vContc || current_cs->packet_type == vConts)
current_cs->nonstop_pending = none_pending;
+ if (current_cs->packet_type == vStopped && notify_buffer)
+ {
+ char okay_buf[4];
+ write_ok (okay_buf);
+ putpkt (okay_buf);
+ putpkt_notif (notify_buffer);
+ xfree (notify_buffer);
+ notify_buffer = 0;
+ return 0;
+ }
+
for (same_pid_cs = client_states.first;
same_pid_cs != NULL;
same_pid_cs = same_pid_cs->next)
@@ -623,6 +655,17 @@ setup_multiplexing (client_state *current_cs)
if (non_stop && (same_pid_cs->catch_syscalls))
continue;
+ /* TODO Protect against a shadow client changing the current thread.
+ This attempted to do that but was invasive.
+ So is intercepting Hg packets */
+ if (0 && current_cs->packet_type == g_or_m)
+ if (!ptid_equal (same_pid_cs->new_general_thread, current_cs->new_general_thread))
+ {
+ sprintf (own_buffer, "E00");
+ putpkt (own_buffer);
+ return 0;
+ }
+
switch (same_pid_cs->pending)
{
case /* same_pid_cs->pending */ none_pending:
@@ -671,11 +714,11 @@ setup_multiplexing (client_state *current_cs)
/* Current client is continuing and found another waiter client */
case /* current_cs->packet_type */ vContc:
{
- int have_nonwaiter;
- analyze_group (current_cs, &have_nonwaiter);
+ int have_waitee;
+ analyze_group (current_cs, &have_waitee);
dump_client_state (__FUNCTION__, "waitee/waiter switch");
/* Don't want to deadlock on everyone waiting */
- if (current_cs->pending == pending_waitee && have_nonwaiter)
+ if (current_cs->pending == pending_waitee && have_waitee)
current_cs->pending = pending_cont_waiter;
}
break;
@@ -715,7 +758,6 @@ setup_multiplexing (client_state *current_cs)
{
case pending_cont_waiter:
case pending_step_waiter:
- case pending_stop:
switch (current_cs->last_packet_type)
{
case vRun:
@@ -740,8 +782,10 @@ setup_multiplexing (client_state *current_cs)
}
+/* Send a notification to a shadow client. */
+
int
-notify_clients (char *buffer)
+notify_clients (char *buffer, int have_first_notify)
{
client_state *same_pid_cs = NULL;
int save_client_fd = client_states.current_fd;
@@ -749,7 +793,6 @@ notify_clients (char *buffer)
char *okay_buf = alloca (4);
int have_syscall = 0;
- debug_printf ("%s DBG %s %s\n", __FUNCTION__, target_waitstatus_to_string (&last_status), own_buffer);
dump_client_state (__FUNCTION__, "");
write_ok (okay_buf);
@@ -758,7 +801,7 @@ notify_clients (char *buffer)
same_pid_cs != NULL;
same_pid_cs = same_pid_cs->next)
{
- /* Insure another client is attached to the cs process */
+ /* Is this a client attached to the same process? */
if (! attached_to_same_proc (client_states.current_cs, same_pid_cs))
continue;
@@ -775,7 +818,8 @@ notify_clients (char *buffer)
set_client_state (save_client_fd);
return 1;
case TARGET_WAITKIND_STOPPED:
- if (same_pid_cs->pending == pending_cont_waiter && same_pid_cs->packet_type == vContc)
+ if ((same_pid_cs->pending == pending_cont_waiter
+ && same_pid_cs->packet_type == vContc))
{
CORE_ADDR point_addr;
struct regcache *regcache = same_pid_cs->ss->current_thread_->regcache_data;
@@ -783,9 +827,12 @@ notify_clients (char *buffer)
if (has_client_breakpoint_at (point_addr))
same_pid_cs->nonstop_pending = pending_notifier;
}
-
+ /* Have more than 1 notify so also send to shadow client */
+ if (save_client_cs->packet_type == vStopped)
+ same_pid_cs->nonstop_pending = pending_notifier;
+
default:
- /* A syscall client only gets a syscall packet */
+ /* Only syscall clients need to see a syscall packet */
if (save_client_cs->catch_syscalls)
{
set_client_state (same_pid_cs->file_desc);
@@ -793,19 +840,38 @@ notify_clients (char *buffer)
}
}
- // syscall continue was erroneously caught by by a non syscall client
+ /* syscall continue was erroneously caught by by a non syscall client */
if (save_client_cs->packet_type == other_packet
- && same_pid_cs->catch_syscalls)
+ && same_pid_cs->catch_syscalls)
return 0;
+ /* client wants the notification */
if (same_pid_cs->nonstop_pending == pending_notifier)
{
/* Also send the notification to the attached client */
set_client_state (same_pid_cs->file_desc);
- putpkt (okay_buf);
if (debug_threads)
debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, same_pid_cs->file_desc);
- putpkt_notif (buffer);
+ /* This is the first notification */
+ if (have_first_notify
+ && (is_waiter (same_pid_cs)
+ || (save_client_cs->packet_type != vStopped
+ && same_pid_cs->nonstop_pending == pending_notifier)))
+ {
+ putpkt (okay_buf);
+ putpkt_notif (buffer);
+ }
+ else /* This is another notification in the group */
+ {
+ if (same_pid_cs->packet_type == vStopped)
+ putpkt (buffer);
+ else
+ {
+ /* send notify after we receive vStopped */
+ same_pid_cs->notify_buffer_ = xmalloc (strlen (buffer) + 1);
+ memcpy (same_pid_cs->notify_buffer_, buffer, strlen (buffer) + 1);
+ }
+ }
set_client_state (save_client_fd);
same_pid_cs->pending = none_pending;
same_pid_cs->nonstop_pending = pending_notified;
@@ -813,8 +879,6 @@ notify_clients (char *buffer)
}
if (have_syscall && !save_client_cs->catch_syscalls)
return 0;
- else if (save_client_cs->nonstop_pending == pending_notified)
- return 0;
else
return 1;
}
@@ -852,6 +916,7 @@ do_multiplexing (client_state *current_cs)
switch (current_cs->packet_type)
{
case other_packet:
+ case Hg:
break;
case vContt:
if (current_cs->last_packet_type == vAttach)
@@ -2099,25 +2164,49 @@ handle_monitor_command (char *mon, char *own_buf)
else if (strcmp (mon, "client status") == 0)
{
client_state *csidx;
- char *result = NULL;
+ char *result = "";
+ char *old_result = NULL;
for (csidx = client_states.first; csidx != NULL; csidx = csidx->next)
- if (csidx->pending)
- {
- if (result)
- asprintf (&result, "%sFile descriptor %d, pid %d, is %s with a current %s request\n", result, csidx->file_desc, ptid_get_pid (csidx->ss->general_thread_), pending_types_str[csidx->pending], packet_types_str[csidx->packet_type]);
- else
- asprintf (&result, "File descriptor %d, pid %d, is %s with a current %s request\n", csidx->file_desc, ptid_get_pid (csidx->ss->general_thread_), pending_types_str[csidx->pending], packet_types_str[csidx->packet_type]);
- }
- if (result)
- monitor_output (result);
+ {
+ if (csidx->file_desc > 0)
+ {
+ old_result = result;
+ asprintf (&result, "%s fd %d %s %s is %s", result,
+ csidx->file_desc, target_pid_to_str (csidx->new_general_thread),
+ last_status.kind != TARGET_WAITKIND_IGNORE ? waitkind_str[last_status.kind] : "",
+ pending_types_str[csidx->pending]);
+ strlen (old_result) ? free (old_result) : 0;
+ old_result = result;
+ if (csidx->packet_type)
+ asprintf (&result, "%s with a current %s request\n", result,
+ packet_types_str[csidx->packet_type]);
+ else
+ asprintf (&result, "%s\n", result);
+ strlen (old_result) ? free (old_result) : 0;
+ }
+ }
+ if (strlen (result) > 0)
+ {
+ monitor_output (result);
+ free (result);
+ }
}
else if (strcmp (mon, "client sync") == 0)
{
client_state *csidx;
for (csidx = client_states.first; csidx != NULL; csidx = csidx->next)
- if (csidx->pending == pending_cont_waiter
- || csidx->pending == pending_waitee)
- csidx->pending = none_pending;
+ {
+ if (csidx->pending)
+ {
+ if (csidx->pending == pending_cont_waiter)
+ {
+ if (non_stop)
+ csidx->packet_type = vContt;
+ resolve_waiter (csidx, NULL);
+ }
+ csidx->pending = none_pending;
+ }
+ }
}
else if (strcmp (mon, "help") == 0)
monitor_show_help ();
@@ -2440,7 +2529,7 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
char core_s[21];
const char *name = target_thread_name (ptid);
- // TODO an attached client does not know about multiple inferiors
+ /* TODO an attached client does not know about multiple inferiors */
if (ptid_get_pid (inf->id) != ptid_get_pid (general_thread)
&& attach_count > 0)
return;
@@ -4840,19 +4929,6 @@ process_serial_event (void)
else
return -1;
}
- else
- {
- if (in_buffer)
- {
- xfree (in_buffer);
- in_buffer = 0;
- }
- if (packet_length > 0)
- {
- in_buffer = xmalloc (packet_length);
- memcpy (in_buffer, own_buffer, packet_length);
- }
- }
response_needed = 1;
@@ -5398,7 +5474,8 @@ handle_target_event (int err, gdb_client_data client_data)
{
for (csi = client_states.first; csi != NULL; csi = csi->next)
{
- if (attached_to_same_proc (save_csi, csi))
+ if (attached_to_same_proc (save_csi, csi)
+ && csi->catch_syscalls)
{
save_csi = client_states.current_cs;
csi->nonstop_pending = pending_notifier;
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index c54476e..fe3d1cb 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -84,7 +84,7 @@ typedef int gdb_fildes_t;
/* Functions from server.c. */
extern int handle_serial_event (int err, gdb_client_data client_data);
extern int handle_target_event (int err, gdb_client_data client_data);
-extern int notify_clients (char *buffer);
+extern int notify_clients (char *buffer, int first);
/* Get rid of the currently pending stop replies that match PTID. */
extern void discard_queued_stop_replies (ptid_t ptid);
@@ -163,7 +163,7 @@ struct client_breakpoint
struct client_breakpoint *next;
};
-enum packet_types { other_packet, vContc, vConts, vContt, vRun, vAttach };
+enum packet_types { other_packet, vContc, vConts, vContt, vRun, vAttach, Hg, g_or_m, vStopped };
typedef enum packet_types packet_types;
enum exit_types { no_exit, have_exit, sent_exit };
@@ -180,6 +180,7 @@ struct client_state
int nonstop_pending;
int catch_syscalls;
ptid_t last_cont_ptid;
+ ptid_t new_general_thread;
struct target_waitstatus last_cont_waitstatus;
/* From server.c */
@@ -226,7 +227,7 @@ struct client_state
int pass_signals_[GDB_SIGNAL_LAST];
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-07-19 20:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-19 20:31 [SCM] scox/globalstate: Support successive notifications scox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).