public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/globalstate: Add initial multiple client support.
@ 2015-09-25 2:59 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2015-09-25 2:59 UTC (permalink / raw)
To: archer-commits
The branch, scox/globalstate has been updated
via 589dd9c8abac87fa8306733f9e6b56af97e739fb (commit)
from 53b72aacff3f6171dec3dada5943526912940299 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 589dd9c8abac87fa8306733f9e6b56af97e739fb
Author: Stan Cox <scox@redhat.com>
Date: Thu Sep 24 22:57:27 2015 -0400
Add initial multiple client support.
* event-loop.c (delete_file_handler): Add delete_client_state.
* mem-break.c (has_client_breakpoint_at): New.
* remote-utils.c (get_listen_desc): New.
* server.c (get_client_state, set_client_state)
* server.h (last_status, last_ptid, current_thread)
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/ChangeLog | 30 ++
gdb/gdbserver/event-loop.c | 43 ++
gdb/gdbserver/mem-break.c | 30 ++
gdb/gdbserver/mem-break.h | 4 +
gdb/gdbserver/remote-utils.c | 70 ++--
gdb/gdbserver/remote-utils.h | 3 +-
gdb/gdbserver/server.c | 610 +++++++++++++++++++++++++++--
gdb/gdbserver/server.h | 52 +++-
gdb/testsuite/gdb.server/multi-client.exp | 166 ++++++++
9 files changed, 948 insertions(+), 60 deletions(-)
create mode 100644 gdb/testsuite/gdb.server/multi-client.exp
First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index cf961e2..6c80e10 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,33 @@
+2015-09-24 Stan Cox <scox@redhat.com>
+
+ * server.c (get_client_state, set_client_state)
+ (delete_client_breakpoint, free_client_state, add_client_by_pid)
+ (add_client_by_exe, get_first_client_fd, have_multiple_clients)
+ (delete_client_state, add_client_breakpoint) New for managing
+ client/server structures.
+ (pending_types, get_pack_type, resolve_waiter, setup_multiplexing)
+ (setup_multiplexing, do_multiplexing) New for managing run state
+ of clients.
+ (start_inferior): Add client to list.
+ (handle_monitor_command): Add 'client status'
+ (process_serial_event): Manage multiple client connections. Call
+ (setup,do)_multiplexing.
+
+ * server.h (last_status, last_ptid, current_thread)
+ (exit_requested): Add union as access macro alternative
+ (client_breakpoint): New struct.
+ (file_desc, executable, packet_type, last_packet_type, pending): New.
+
+ * event-loop.c (delete_file_handler): Add delete_client_state.
+ (handle_file_event): Reset file descriptor for multiple clients.
+ (wait_for_event): Handle additional client connections.
+
+ * mem-break.c (has_client_breakpoint_at): New.
+
+ * remote-utils.c (get_listen_desc): New.
+ (handle_accept_event): Unset noack_mode.
+ (write_prim, write, read_prim, readchar, getpkt): Add file desc parm.
+
2015-09-12 Stan Cox <scox@redhat.com>
* gdbthread.h (last_status): Rename last_waitstatus to avoid conflict
diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index dd07093..3724cd7 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -385,6 +385,8 @@ delete_file_handler (gdb_fildes_t fd)
;
prev_ptr->next_file = file_ptr->next_file;
}
+
+ delete_client_state (fd);
free (file_ptr);
}
@@ -425,6 +427,9 @@ handle_file_event (gdb_fildes_t event_file_desc)
/* If there was a match, then call the handler. */
if (mask != 0)
{
+ /* Don't change client states if we have multiple clients */
+ if (have_multiple_clients ())
+ set_client_state (file_ptr->fd);
if ((*file_ptr->proc) (file_ptr->error,
file_ptr->client_data) < 0)
return -1;
@@ -465,6 +470,38 @@ wait_for_event (void)
file_handler *file_ptr;
int num_found = 0;
+ /* Do we have another client? */
+ fd_set conn_fd_set;
+ struct timeval timeout;
+ FD_ZERO(&conn_fd_set);
+ FD_SET(get_listen_desc(),&conn_fd_set);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10;
+ num_found = select (FD_SETSIZE, &conn_fd_set, NULL, NULL, &timeout);
+ if (debug_threads > 1)
+ fprintf (stderr,"%s select fd=%d found=%d\n",__FUNCTION__,get_listen_desc(),num_found);
+ if (num_found > 0)
+ {
+ int i;
+ for (i = 1; i < FD_SETSIZE; ++i)
+ if (FD_ISSET (i, &conn_fd_set))
+ {
+ if (i == get_listen_desc())
+ {
+ int handle_accept_event (int, gdb_client_data);
+ if (debug_threads > 1)
+ fprintf (stderr,"%s in select idx %d\n",__FUNCTION__,i);
+ /* instead of using gdb_event just setup the connection "by hand" */
+ handle_accept_event (0, NULL);
+ add_file_handler (get_remote_desc(), handle_serial_event, get_client_state());
+ }
+ else
+ if (debug_threads > 1)
+ fprintf (stderr,"%s data arrived on existing connection %d fd=%d\n", __FUNCTION__, i,get_listen_desc());
+ }
+ }
+ /* */
+
/* Make sure all output is done before getting another event. */
fflush (stdout);
fflush (stderr);
@@ -520,8 +557,14 @@ wait_for_event (void)
if (file_ptr->ready_mask == 0)
{
+ int handle_accept_event (int err, gdb_client_data client_data);
gdb_event *file_event_ptr = create_file_event (file_ptr->fd);
+ if (debug_threads > 1)
+ {
+ fprintf (stderr,"%s #fds=%d\n",__FUNCTION__,gdb_notifier.num_fds);
+ fprintf(stderr,"%s create_file_event for %d %#lx %#lx %#lx %#lx\n",__FUNCTION__,file_event_ptr->fd,(long unsigned int)file_ptr->proc,(long unsigned int)handle_file_event,(long unsigned int)handle_serial_event,(long unsigned int)handle_accept_event);
+ }
QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
}
file_ptr->ready_mask = mask;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 9356741..138e8e0 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -293,6 +293,36 @@ find_raw_breakpoint_at (CORE_ADDR addr, enum raw_bkpt_type type, int size)
return NULL;
}
+/* Is there a low-level breakpoint at address ADDR? */
+
+int
+has_client_breakpoint_at (CORE_ADDR addr)
+{
+ client_state *cs = get_client_state ();
+
+ struct client_breakpoint *cb;
+ if (debug_threads)
+ debug_printf ("%s:%d fd=%d addr=%#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)addr);
+ for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next)
+ if (debug_threads)
+ debug_printf ("%s:%d %d breakpoint at %#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)cb->addr);
+
+ // for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
+ {
+ // if (addr >= bp->pc && addr <= bp->pc + 8 && cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED
+ // && cs->ss->last_status.value.sig == GDB_SIGNAL_TRAP)
+ for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next)
+ // TODO improve this; pc might be one insn ahead of break.
+ {
+ debug_printf ("%s:%d addr=%#lx pb->pc %#lx in range? %d\n", __FUNCTION__, __LINE__, (long unsigned) addr, (long unsigned)cb->addr, addr >= cb->addr && addr <= cb->addr + 8);
+ if (addr >= cb->addr && addr <= cb->addr + 8)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
/* See mem-break.h. */
int
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
index b5a3208..9f737d0 100644
--- a/gdb/gdbserver/mem-break.h
+++ b/gdb/gdbserver/mem-break.h
@@ -245,6 +245,10 @@ void uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc);
void reinsert_fast_tracepoint_jumps_at (CORE_ADDR where);
+/* Does a client have a breakpoint at addr? */
+
+int has_client_breakpoint_at (CORE_ADDR addr);
+
/* Insert a memory breakpoint. */
int insert_memory_breakpoint (struct raw_breakpoint *bp);
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 67268ea..d2b3b85 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -88,7 +88,7 @@ enum {
Either NOT_SCHEDULED or the callback id. */
static int readchar_callback = NOT_SCHEDULED;
-static int readchar (void);
+static int readchar (gdb_fildes_t);
static void reset_readchar (void);
static void reschedule (void);
@@ -136,6 +136,12 @@ set_remote_desc (gdb_fildes_t fd)
}
int
+get_listen_desc ()
+{
+ return listen_desc;
+}
+
+int
gdb_connected (void)
{
return remote_desc != INVALID_DESCRIPTOR;
@@ -163,7 +169,7 @@ enable_async_notification (int fd)
#endif
}
-static int
+int
handle_accept_event (int err, gdb_client_data client_data)
{
struct sockaddr_in sockaddr;
@@ -172,11 +178,14 @@ handle_accept_event (int err, gdb_client_data client_data)
if (debug_threads)
debug_printf ("handling possible accept event\n");
+ noack_mode = 0;
tmp = sizeof (sockaddr);
remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
if (remote_desc == -1)
perror_with_name ("Accept failed");
+ set_client_state (remote_desc);
+
/* Enable TCP keep alive process. */
tmp = 1;
setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
@@ -193,7 +202,8 @@ handle_accept_event (int err, gdb_client_data client_data)
exits when the remote side dies. */
#endif
- if (run_once)
+ /* TODO check this */
+ if (0 && run_once)
{
#ifndef USE_WIN32API
close (listen_desc); /* No longer need this */
@@ -204,7 +214,8 @@ handle_accept_event (int err, gdb_client_data client_data)
/* Even if !RUN_ONCE no longer notice new connections. Still keep the
descriptor open for add_file_handler to wait for a new connection. */
- delete_file_handler (listen_desc);
+ // TODO check this
+ // delete_file_handler (listen_desc);
/* Convert IP address to string. */
fprintf (stderr, "Remote debugging from host %s\n",
@@ -601,12 +612,12 @@ read_ptid (char *buf, char **obuf)
This may return less than COUNT. */
static int
-write_prim (const void *buf, int count)
+write_prim (gdb_fildes_t fd, const void *buf, int count)
{
if (remote_connection_is_stdio ())
return write (fileno (stdout), buf, count);
else
- return write (remote_desc, buf, count);
+ return write (fd, buf, count);
}
/* Read COUNT bytes from the client and store in BUF.
@@ -614,12 +625,12 @@ write_prim (const void *buf, int count)
This may return less than COUNT. */
static int
-read_prim (void *buf, int count)
+read_prim (gdb_fildes_t fd, void *buf, int count)
{
if (remote_connection_is_stdio ())
return read (fileno (stdin), buf, count);
else
- return read (remote_desc, buf, count);
+ return read (fd, buf, count);
}
/* Send a packet to the remote machine, with error checking.
@@ -634,6 +645,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
char *buf2;
char *p;
int cc;
+ client_state *cs = get_client_state();
buf2 = xmalloc (strlen ("$") + cnt + strlen ("#nn") + 1);
@@ -659,7 +671,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
do
{
- if (write_prim (buf2, p - buf2) != p - buf2)
+ if (write_prim (cs->file_desc, buf2, p - buf2) != p - buf2)
{
perror ("putpkt(write)");
free (buf2);
@@ -672,9 +684,9 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
if (remote_debug)
{
if (is_notif)
- fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2);
+ fprintf (stderr, "putpkt/%d (\"%s\"); [notif]\n", cs->file_desc, buf2);
else
- fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
+ fprintf (stderr, "putpkt/%d (\"%s\"); [noack mode]\n", cs->file_desc, buf2);
fflush (stderr);
}
break;
@@ -682,11 +694,11 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
if (remote_debug)
{
- fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
+ fprintf (stderr, "putpkt/%d (\"%s\"); [looking for ack]\n", cs->file_desc, buf2);
fflush (stderr);
}
- cc = readchar ();
+ cc = readchar (cs->file_desc);
if (cc < 0)
{
@@ -754,7 +766,7 @@ input_interrupt (int unused)
int cc;
char c = 0;
- cc = read_prim (&c, 1);
+ cc = read_prim (remote_desc, &c, 1);
if (cc == 0)
{
@@ -877,13 +889,13 @@ initialize_async_io (void)
/* Returns next char from remote GDB. -1 if error. */
static int
-readchar (void)
+readchar (gdb_fildes_t fd)
{
int ch;
if (readchar_bufcnt == 0)
{
- readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
+ readchar_bufcnt = read_prim (fd, readchar_buf, sizeof (readchar_buf));
if (readchar_bufcnt <= 0)
{
@@ -949,7 +961,7 @@ reschedule (void)
and store it in BUF. Returns length of packet, or negative if error. */
int
-getpkt (char *buf)
+getpkt (gdb_fildes_t fd, char *buf)
{
char *bp;
unsigned char csum, c1, c2;
@@ -961,7 +973,7 @@ getpkt (char *buf)
while (1)
{
- c = readchar ();
+ c = readchar (fd);
if (c == '$')
break;
if (remote_debug)
@@ -977,7 +989,7 @@ getpkt (char *buf)
bp = buf;
while (1)
{
- c = readchar ();
+ c = readchar (fd);
if (c < 0)
return -1;
if (c == '#')
@@ -987,8 +999,8 @@ getpkt (char *buf)
}
*bp = 0;
- c1 = fromhex (readchar ());
- c2 = fromhex (readchar ());
+ c1 = fromhex (readchar (fd));
+ c2 = fromhex (readchar (fd));
if (csum == (c1 << 4) + c2)
break;
@@ -1005,7 +1017,7 @@ getpkt (char *buf)
fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
(c1 << 4) + c2, csum, buf);
- if (write_prim ("-", 1) != 1)
+ if (write_prim (fd, "-", 1) != 1)
return -1;
}
@@ -1013,11 +1025,11 @@ getpkt (char *buf)
{
if (remote_debug)
{
- fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf);
+ fprintf (stderr, "getpkt/%d (\"%s\"); [sending ack] \n", fd, buf);
fflush (stderr);
}
- if (write_prim ("+", 1) != 1)
+ if (write_prim (fd, "+", 1) != 1)
return -1;
if (remote_debug)
@@ -1030,7 +1042,7 @@ getpkt (char *buf)
{
if (remote_debug)
{
- fprintf (stderr, "getpkt (\"%s\"); [no ack sent] \n", buf);
+ fprintf (stderr, "getpkt/%d (\"%s\"); [no ack sent] \n", fd, buf);
fflush (stderr);
}
}
@@ -1451,7 +1463,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
return -1;
/* FIXME: Eventually add buffer overflow checking (to getpkt?) */
- len = getpkt (own_buf);
+ len = getpkt (remote_desc, own_buf);
if (len < 0)
return -1;
@@ -1475,7 +1487,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
free (mem_buffer);
if (putpkt (own_buf) < 0)
return -1;
- len = getpkt (own_buf);
+ len = getpkt (remote_desc, own_buf);
if (len < 0)
return -1;
}
@@ -1534,7 +1546,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
return -1;
/* FIXME: Eventually add buffer overflow checking (to getpkt?) */
- len = getpkt (own_buf);
+ len = getpkt (remote_desc, own_buf);
if (len < 0)
return -1;
@@ -1577,7 +1589,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
free (mem_buffer);
if (putpkt (own_buf) < 0)
return -1;
- len = getpkt (own_buf);
+ len = getpkt (remote_desc, own_buf);
if (len < 0)
return -1;
}
diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h
index 2a1c62f..32f0b52 100644
--- a/gdb/gdbserver/remote-utils.h
+++ b/gdb/gdbserver/remote-utils.h
@@ -25,6 +25,7 @@ extern int transport_is_reliable;
int get_remote_desc (void);
void set_remote_desc (gdb_fildes_t);
+int get_listen_desc (void);
int gdb_connected (void);
@@ -37,7 +38,7 @@ char *write_ptid (char *buf, ptid_t ptid);
int putpkt (char *buf);
int putpkt_binary (char *buf, int len);
int putpkt_notif (char *buf);
-int getpkt (char *buf);
+int getpkt (gdb_fildes_t,char *buf);
void remote_prepare (char *name);
void remote_open (char *name);
void remote_close (void);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 9838a6f..07828c2 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -83,33 +83,520 @@ DEFINE_QUEUE_P (notif_event_p);
static struct client_states client_states;
+static void handle_status (char *);
+
+
+/* Return the current client state */
+
+extern inline client_state*
+get_client_state (void)
+{
+ return client_states.current_cs;
+}
+
/* Add a new client state for fd or return if found */
client_state *
set_client_state (gdb_fildes_t fd)
{
- if (client_states.first == NULL)
+/* States:
+ * fd = -1 add initial client state
+ * fd = F add client state for fd F
+ */
+
+ client_state *csidx;
+
+ /* add/return initial client state */
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-09-25 2:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-25 2:59 [SCM] scox/globalstate: Add initial multiple client support 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).