From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 43295 invoked by alias); 8 May 2016 16:32:23 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 43276 invoked by uid 440); 8 May 2016 16:32:22 -0000 Date: Sun, 08 May 2016 16:32:00 -0000 Message-ID: <20160508163222.43246.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/globalstate: Support non-stop mode for syscall clients. X-Git-Refname: refs/heads/scox/globalstate X-Git-Reftype: branch X-Git-Oldrev: 0b038592634fba79da5353187a75028e81b6a718 X-Git-Newrev: 6428d6072f707614f36cf6aa29d0591bd3608400 X-SW-Source: 2016-q2/txt/msg00000.txt.bz2 List-Id: 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 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 + + * 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 * 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 #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.