public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/globalstate: Support non-stop mode for syscall clients.
@ 2016-05-08 16:32 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2016-05-08 16:32 UTC (permalink / raw)
To: archer-commits
The branch, scox/globalstate has been updated
via 6428d6072f707614f36cf6aa29d0591bd3608400 (commit)
from 0b038592634fba79da5353187a75028e81b6a718 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 6428d6072f707614f36cf6aa29d0591bd3608400
Author: Stan Cox <scox@redhat.com>
Date: Sun May 8 12:30:21 2016 -0400
Support non-stop mode for syscall clients.
* remote-utils.c (remote_debug, noack_mode)
(transport_is_reliable): Move to ...
* server.h: ...here
* server.c (setup_multiplexing): Don't special case syscall clients.
(notify_clients): syscall clients only get syscall notifications
(do_multiplexing): Explicitly send notifications to syscall client.
(dump_stop_queue): New.
(handle_target_event): Don't want the current client to be a
syscall client.
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/ChangeLog | 12 ++
gdb/gdbserver/hostio.c | 2 -
gdb/gdbserver/remote-utils.c | 11 +--
gdb/gdbserver/remote-utils.h | 4 -
gdb/gdbserver/server.c | 171 ++++++++++++++++++++++++-----
gdb/gdbserver/server.h | 15 +++
gdb/gdbserver/target.c | 1 +
gdb/testsuite/gdb.server/multi-client.exp | 19 ++--
8 files changed, 183 insertions(+), 52 deletions(-)
First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index f1589f9..4b1f56a 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,15 @@
+2016-05-08 Stan Cox <scox@redhat.com>
+
+ * remote-utils.c (remote_debug, noack_mode)
+ (transport_is_reliable): Move to ...
+ * server.h: ...here
+ * server.c (setup_multiplexing): Don't special case syscall clients.
+ (notify_clients): syscall clients only get syscall notifications
+ (do_multiplexing): Explicitly send notifications to syscall client.
+ (dump_stop_queue): New.
+ (handle_target_event): Don't want the current client to be a
+ syscall client.
+
2016-03-30 Stan Cox <scox@redhat.com>
* server.c (pending_types): Add pending_notifier
diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c
index 242206e..dcdcdc8 100644
--- a/gdb/gdbserver/hostio.c
+++ b/gdb/gdbserver/hostio.c
@@ -29,8 +29,6 @@
#include <sys/stat.h>
#include "fileio.h"
-extern int remote_debug;
-
struct fd_list
{
int fd;
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index f65f572..5c01675 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -100,7 +100,6 @@ struct sym_cache
struct sym_cache *next;
};
-int remote_debug = 0;
struct ui_file *gdb_stdlog;
static int remote_is_stdio = 0;
@@ -112,11 +111,6 @@ static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
extern int using_threads;
extern int debug_threads;
-/* If true, then GDB has requested noack mode. */
-int noack_mode = 0;
-/* If true, then we tell GDB to use noack mode by default. */
-int transport_is_reliable = 0;
-
#ifdef USE_WIN32API
# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
@@ -178,13 +172,13 @@ 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);
+ noack_mode = 0;
/* Enable TCP keep alive process. */
tmp = 1;
@@ -232,7 +226,8 @@ handle_accept_event (int err, gdb_client_data client_data)
try to send vStopped notifications to GDB. But, don't do that
until GDB as selected all-stop/non-stop, and has queried the
threads' status ('?'). */
- target_async (0);
+
+ //TODO target_async (0);
return 0;
}
diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h
index 4273bf2..f559f00 100644
--- a/gdb/gdbserver/remote-utils.h
+++ b/gdb/gdbserver/remote-utils.h
@@ -19,10 +19,6 @@
#ifndef REMOTE_UTILS_H
#define REMOTE_UTILS_H
-extern int remote_debug;
-extern int noack_mode;
-extern int transport_is_reliable;
-
int get_remote_desc (void);
void set_remote_desc (gdb_fildes_t);
int get_listen_desc (void);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 9ae8bda..78cfb9a 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -269,6 +269,7 @@ static void free_client_state (client_state *cs)
/* Dump the client state list for debugging purposes */
+static void dump_stop_queue(const char*,const char*);
void
dump_client_state (const char *function, const char *comment)
{
@@ -277,8 +278,9 @@ dump_client_state (const char *function, const char *comment)
if (! debug_threads)
return;
-
- debug_printf ("***Begin Dumping client state from %s %s\n", function, comment);
+
+ dump_stop_queue (function, comment);
+ debug_printf ("** client state at %s: %s\n", function, comment);
for (cs = client_states.first; cs != NULL; cs = cs->next)
{
char *last_status_kind;
@@ -298,10 +300,10 @@ dump_client_state (const char *function, const char *comment)
if (regcache != NULL)
pc = (*the_target->read_pc) (regcache);
if (save_cs == cs)
- debug_printf ("*");
+ debug_printf (" *");
else
- debug_printf (" ");
- debug_printf ("%d %#lx pc=%#lx #=%d %s %s %s %s\n",
+ debug_printf (" ");
+ debug_printf ("%d %lu pc=%#lx #=%d %s %s %s %s\n",
cs->file_desc,
(long unsigned)general_thread.pid,
(long unsigned)pc,
@@ -311,7 +313,6 @@ dump_client_state (const char *function, const char *comment)
pending_types_str[cs->pending],
last_status_kind);
}
- debug_printf ("***End Dumping client state\n");
client_states.current_cs = save_cs;
}
@@ -342,16 +343,23 @@ add_client_by_pid (int pid)
/* Return the first active client state */
-gdb_fildes_t
-get_first_client_fd (void)
+client_state*
+get_first_client (void)
{
client_state *cs;
for (cs = client_states.first; cs != NULL; cs = cs->next)
{
if (cs->file_desc > 0 && cs->attached_to_client == 1)
- return cs->file_desc;
+ return cs;
}
- return -1;
+ return client_states.first;
+}
+
+gdb_fildes_t
+get_first_client_fd (void)
+{
+ client_state *cs = get_first_client ();
+ return cs->file_desc;
}
@@ -520,7 +528,7 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
}
case vConts:
{
- if (non_stop)
+ if (non_stop)
{
if (last_status.kind != TARGET_WAITKIND_EXITED
&& last_status.kind != TARGET_WAITKIND_STOPPED)
@@ -601,8 +609,9 @@ void
analyze_group (client_state *current_cs, int *have_nonwaiter)
{
client_state *csi;
- *have_nonwaiter = 0;
+ *have_nonwaiter = 0;
+
for (csi = client_states.first->next; csi != NULL; csi = csi->next)
{
if (attached_to_same_proc (current_cs, csi))
@@ -651,6 +660,9 @@ setup_multiplexing (client_state *current_cs)
if (! attached_to_same_proc (current_cs, same_pid_cs))
continue;
+ if (non_stop && (same_pid_cs->catch_syscalls /*|| current_cs->catch_syscalls*/))
+ continue;
+
switch (same_pid_cs->pending)
{
case /* same_pid_cs->pending */ none_pending:
@@ -721,7 +733,10 @@ setup_multiplexing (client_state *current_cs)
/* Current client is continuing and found another waitee client */
case /* current_cs->packet_type */ vContc:
{
- current_cs->pending = pending_cont_waiter;
+ if (!(non_stop
+ && current_cs->catch_syscalls
+ && same_pid_cs->packet_type == vContc))
+ current_cs->pending = pending_cont_waiter;
}
break;
case /* current_cs->packet_type */ vConts:
@@ -729,6 +744,7 @@ setup_multiplexing (client_state *current_cs)
current_cs->pending = pending_step_waiter;
}
}
+ debug_printf ("%s DBG %s catching=%d\n", __FUNCTION__, target_waitstatus_to_string (&last_status), current_cs->catch_syscalls);
} /* switch same_pid_cs->pending */
} /* for same_pid_cs */
@@ -746,16 +762,17 @@ setup_multiplexing (client_state *current_cs)
/* Current client is continuing and waiting so don't reply to this
packet now; it will be replied to later in do_multiplexing */
- if (current_cs->ss->last_status_exited != have_exit)
+ if (current_cs->ss->last_status_exited != have_exit
+ && !(current_cs->catch_syscalls && current_cs->packet_type != vContc))
{
- dump_client_state (__FUNCTION__, "return 0");
+ dump_client_state (__FUNCTION__, "* waiting");
current_cs->last_cont_ptid = current_cs->ss->general_thread_;
current_cs->last_cont_waitstatus = current_cs->ss->last_status_;
return 0; /* Reply to packet later */
}
} /* switch current_cs->last_packet_type */
default: /* fall through */
- dump_client_state (__FUNCTION__, "return 1");
+ dump_client_state (__FUNCTION__, "* continuing");
return 1; /* Reply to packet now */
} /* switch current_cs->pending */
}
@@ -769,6 +786,9 @@ notify_clients (char *buffer)
client_state *save_client_cs = client_states.current_cs;
char *okay_buf = alloca (4);
+ debug_printf ("%s DBG %s %s\n", __FUNCTION__, target_waitstatus_to_string (&last_status), own_buffer);
+ dump_client_state (__FUNCTION__, "");
+
write_ok (okay_buf);
for (same_pid_cs = client_states.first;
@@ -778,6 +798,16 @@ notify_clients (char *buffer)
/* Insure another client is attached to the cs process */
if (! attached_to_same_proc (client_states.current_cs, same_pid_cs))
continue;
+ /* Insure a syscall client only gets a syscall packet */
+ if (last_status.kind != TARGET_WAITKIND_SYSCALL_ENTRY
+ && last_status.kind != TARGET_WAITKIND_SYSCALL_RETURN
+ && save_client_cs->catch_syscalls)
+ {
+ debug_printf ("%s DBG switch %d and %d %s %s\n", __FUNCTION__, save_client_fd, same_pid_cs->file_desc, save_client_cs->own_buffer_, same_pid_cs->own_buffer_);
+ set_client_state (same_pid_cs->file_desc);
+ return;
+ }
+
if (same_pid_cs->pending == pending_notifier)
{
if (debug_threads)
@@ -830,6 +860,9 @@ stop_clients (client_state *current_cs)
/* Resolve the state of client WAITEE_CS with respect to other clients connected to the same server process */
+static void
+push_stop_notification (ptid_t ptid, struct target_waitstatus *status);
+
static int
do_multiplexing (client_state *current_cs)
{
@@ -880,6 +913,8 @@ do_multiplexing (client_state *current_cs)
if (current_cs->pending == pending_waitee)
break;
default: /* fall through */
+ if (current_cs->catch_syscalls)
+ break;
dump_client_state (__FUNCTION__, "no action taken");
return 1;
}
@@ -898,6 +933,23 @@ do_multiplexing (client_state *current_cs)
/* Insure another client is attached to the cs process */
if (! attached_to_same_proc (current_cs, same_pid_cs))
continue;
+
+ if (non_stop &&
+ ((same_pid_cs->catch_syscalls
+ && (current_cs->packet_type == vConts || current_cs->packet_type == vContc))
+ || (current_cs->catch_syscalls
+ && (same_pid_cs->packet_type == vConts || same_pid_cs->packet_type == vContc))))
+ {
+ /* Explicit write of notification and remove from queue */
+ if (same_pid_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+ || same_pid_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_RETURN)
+ {
+ set_client_state (same_pid_cs->file_desc);
+ handle_target_event (0, 0);
+ set_client_state (current_cs->file_desc);
+ }
+ }
+
switch (same_pid_cs->pending)
{
case /* same_pid_cs->pending */ pending_cont_waiter:
@@ -905,13 +957,38 @@ do_multiplexing (client_state *current_cs)
switch (same_pid_cs->packet_type)
{
case /* same_pid_cs->packet_type */ vContc:
- prepare_to_access_memory ();
+ if (same_pid_cs->non_stop_ && same_pid_cs->catch_syscalls
+ && (current_cs->packet_type == vConts || current_cs->packet_type == vContc))
+ {
+ /* Explicit write of notification and remove from queue */
+ if (same_pid_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+ || same_pid_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_RETURN)
+ {
+ set_client_state (same_pid_cs->file_desc);
+ handle_target_event (0, 0);
+ set_client_state (current_cs->file_desc);
+ }
+ else
+ {
+ handle_target_event (0, 0);
+ }
+ break;
+ }
+
if (current_cs->packet_type == vContc
&& (current_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_ENTRY
|| current_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_RETURN))
{
if (same_pid_cs->catch_syscalls)
{
+ if (same_pid_cs->non_stop_)
+ {
+ if (debug_threads)
+ debug_printf ("%s handle_target_event\n", __FUNCTION__);
+ handle_target_event (0, 0);
+ break;
+ }
+
resolve_waiter (same_pid_cs, current_cs);
dump_client_state (__FUNCTION__, "resolved syscall");
same_pid_cs->pending = pending_waitee;
@@ -942,15 +1019,16 @@ do_multiplexing (client_state *current_cs)
struct regcache *regcache;
struct thread_info *thread;
CORE_ADDR pc;
+
if (non_stop)
{
thread = current_thread;
- regcache = get_thread_regcache (thread, 1);
+ regcache = client_states.current_cs->ss->current_thread_->regcache_data;
}
else
{
thread = find_thread_ptid (last_ptid);
- regcache = get_thread_regcache (thread, 1);
+ regcache = client_states.current_cs->ss->current_thread_->regcache_data;
}
pc = (*the_target->read_pc) (regcache);
current_cs_has_bp = has_client_breakpoint_at (pc);
@@ -982,7 +1060,6 @@ do_multiplexing (client_state *current_cs)
debug_printf ("%s:%d fd=%d no breakpoint\n", __FUNCTION__, __LINE__, waiter_cs->file_desc);
}
current_cs = set_client_state (current_cs->file_desc);
- done_accessing_memory ();
} /* switch same_pid_cs->packet_type */
break; /* case vContc */
@@ -1006,14 +1083,14 @@ do_multiplexing (client_state *current_cs)
{
/* The packet will be replied to later in do_multiplexing */
current_cs->pending = pending_cont_waiter;
- dump_client_state (__FUNCTION__, "return 0");
+ dump_client_state (__FUNCTION__, "* waiting");
current_cs->last_cont_ptid = current_cs->ss->general_thread_;
current_cs->last_cont_waitstatus = current_cs->ss->last_status_;
return 0;
}
else
{
- dump_client_state (__FUNCTION__, "return 1");
+ dump_client_state (__FUNCTION__, "* continuing");
return 1;
}
}
@@ -1217,8 +1294,6 @@ attach_inferior (int pid)
return 0;
}
-extern int remote_debug;
-
/* Decode a qXfer read request. Return 0 if everything looks OK,
or -1 otherwise. */
@@ -4628,7 +4703,6 @@ captured_main (int argc, char *argv[])
while (1)
{
-
noack_mode = 0;
/* Be sure we're out of tfind mode. */
current_traceframe = -1;
@@ -4936,9 +5010,7 @@ process_serial_event (void)
fprintf (stderr, "Detaching from process %d\n", pid);
stop_tracing ();
- if (cs->ss->attach_count_ > 0)
- write_ok (own_buffer);
- else if (detach_inferior (pid) != 0)
+ if (detach_inferior (pid) != 0)
write_enn (own_buffer);
else
{
@@ -5298,7 +5370,7 @@ process_serial_event (void)
break;
}
- if (! do_multiplexing (cs))
+ if (! do_multiplexing (get_client_state()))
return 0;
if (new_packet_len != -1)
@@ -5334,6 +5406,28 @@ handle_serial_event (int err, gdb_client_data client_data)
return 0;
}
+/* Dump stop notifications */
+
+static void
+dump_stop_queue (const char *function, const char *comment)
+{
+ struct queue_elem_notif_event_p *queue_elem;
+ struct vstop_notif *vstop_notif;
+ struct notif_server x;
+
+ if (!debug_threads || (struct queue_elem_notif_event_p*)(notif_stop.queue)->head == NULL)
+ return;
+ debug_printf ("** stop queue at %s: %s\n", function, comment);
+ for (queue_elem = (struct queue_elem_notif_event_p*)(notif_stop.queue)->head;
+ queue_elem != 0;
+ queue_elem = queue_elem->next)
+ {
+ vstop_notif = (struct vstop_notif*)queue_elem->data;
+ debug_printf ("%d %s\n", vstop_notif->ptid.pid, target_waitstatus_to_string (&vstop_notif->status));
+ }
+}
+
+
/* Push a stop notification on the notification queue. */
static void
@@ -5352,6 +5446,8 @@ push_stop_notification (ptid_t ptid, struct target_waitstatus *status)
int
handle_target_event (int err, gdb_client_data client_data)
{
+ client_state *csi, *save_csi;
+
if (debug_threads)
debug_printf ("handling possible target event\n");
@@ -5361,6 +5457,7 @@ handle_target_event (int err, gdb_client_data client_data)
if (debug_threads)
debug_printf ("%s fd=%d queue=%d %s\n", __FUNCTION__, client_states.current_fd, notif_stop.queue->head == NULL ? 0 : 1,
waitkind_str[last_status.kind]);
+ save_csi = client_states.current_cs;
if (last_status.kind == TARGET_WAITKIND_NO_RESUMED)
{
@@ -5373,6 +5470,21 @@ handle_target_event (int err, gdb_client_data client_data)
struct process_info *process = find_process_pid (pid);
int forward_event = !gdb_connected () || process->gdb_detached;
+ if ((last_status.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+ || last_status.kind == TARGET_WAITKIND_SYSCALL_RETURN)
+ && have_multiple_clients (client_states.current_fd))
+ {
+ for (csi = client_states.first; csi != NULL; csi = csi->next)
+ {
+ if (attached_to_same_proc (save_csi, csi))
+ {
+ save_csi = client_states.current_cs;
+ csi->pending = pending_notifier;
+ break;
+ }
+ }
+ }
+
if (last_status.kind == TARGET_WAITKIND_EXITED
|| last_status.kind == TARGET_WAITKIND_SIGNALLED)
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-05-08 16:32 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-08 16:32 [SCM] scox/globalstate: Support non-stop mode for syscall clients 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).