From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 127333 invoked by alias); 25 May 2016 18:22:30 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 127304 invoked by uid 440); 25 May 2016 18:22:29 -0000 Date: Wed, 25 May 2016 18:22:00 -0000 Message-ID: <20160525182229.127276.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/globalstate: Improve syscall and exit notification handling. X-Git-Refname: refs/heads/scox/globalstate X-Git-Reftype: branch X-Git-Oldrev: 6428d6072f707614f36cf6aa29d0591bd3608400 X-Git-Newrev: b9d4c5aefb38b48611ca88feab071a8eacf4be60 X-SW-Source: 2016-q2/txt/msg00001.txt.bz2 List-Id: The branch, scox/globalstate has been updated via b9d4c5aefb38b48611ca88feab071a8eacf4be60 (commit) from 6428d6072f707614f36cf6aa29d0591bd3608400 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit b9d4c5aefb38b48611ca88feab071a8eacf4be60 Author: Stan Cox Date: Wed May 25 14:20:26 2016 -0400 Improve syscall and exit notification handling. * server.c (free_client_state): Free in_buffer and own_buffer. (notify_clients): Syscall clients only get syscall notify. Handle exit notify. (stop_clients): Handled by notify_clients. (do_multiplexing): Handle syscall notify in notify_clients. ----------------------------------------------------------------------- Summary of changes: gdb/gdbserver/ChangeLog | 8 +++ gdb/gdbserver/server.c | 136 +++++++++++------------------------------------ gdb/gdbserver/server.h | 4 -- 3 files changed, 40 insertions(+), 108 deletions(-) First 500 lines of diff: diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 4b1f56a..d8b72e1 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +2016-05-25 Stan Cox + + * server.c (free_client_state): Free in_buffer and own_buffer. + (notify_clients): Syscall clients only get syscall notify. Handle + exit notify. + (stop_clients): Handled by notify_clients. + (do_multiplexing): Handle syscall notify in notify_clients. + 2016-05-08 Stan Cox * remote-utils.c (remote_debug, noack_mode) diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 78cfb9a..6639b3f 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -252,17 +252,16 @@ static void free_client_state (client_state *cs) client_state *csi; for (csi = client_states.first; csi != NULL; csi = csi->next) { - if (ptid_equal (csi->ss->general_thread_, null_ptid) - && attached_to_same_proc (cs, csi)) + if (attached_to_same_proc (cs, csi)) break; } delete_client_breakpoint (0); if (csi == NULL) XDELETE (cs->ss); - if (in_buffer) - xfree (in_buffer); - xfree (own_buffer); + if (cs->in_buffer_) + xfree (cs->in_buffer_); + xfree (cs->own_buffer_); XDELETE (cs); } @@ -401,6 +400,7 @@ delete_client_state (gdb_fildes_t fd) } free_client_state (cs); cs = previous_cs; + break; } if (cs->next == NULL) break; @@ -494,11 +494,13 @@ resolve_waiter (client_state *cs, client_state *waitee_cs) new_notif->ptid = general_thread; new_notif->status = last_status; new_notif->status.kind = TARGET_WAITKIND_STOPPED; + /* TODO this may incorrectly precede check_stopped_by_breakpoint adjustment of the pc */ notif_push (¬if_stop, (struct notif_event *) new_notif); /* Explicit write of notification and remove from queue */ discard_queued_stop_replies (cs->ss->general_thread_); + debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc); notif_write_event (¬if_stop, notif_buf); } else if (last_status.kind != TARGET_WAITKIND_EXITED) @@ -549,6 +551,8 @@ resolve_waiter (client_state *cs, client_state *waitee_cs) /* Explicit write of notification and remove from queue */ discard_queued_stop_replies (cs->ss->general_thread_); + if (debug_threads) + debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc); notif_write_event (¬if_stop, notif_buf); if (last_status.kind != TARGET_WAITKIND_STOPPED) cs->pending = pending_notifier; @@ -584,6 +588,8 @@ resolve_waiter (client_state *cs, client_state *waitee_cs) // TODO Use Defined notif constant strcpy (out_buf, "Stop:"); strcat (out_buf, notif_buf); + if (debug_threads) + debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc); putpkt_notif (out_buf); if (debug_threads) debug_printf ("%s:%d %s\n", __FUNCTION__, __LINE__, out_buf); @@ -660,7 +666,7 @@ 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*/)) + if (non_stop && (same_pid_cs->catch_syscalls)) continue; switch (same_pid_cs->pending) @@ -798,22 +804,32 @@ 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_); + + switch (last_status.kind) + { + case TARGET_WAITKIND_SYSCALL_ENTRY: + case TARGET_WAITKIND_SYSCALL_RETURN: + break; + case TARGET_WAITKIND_EXITED: set_client_state (same_pid_cs->file_desc); + putpkt (okay_buf); + putpkt_notif (buffer); + set_client_state (save_client_fd); return; - } - + default: + /* A syscall client only gets a syscall packet */ + if (save_client_cs->catch_syscalls) + set_client_state (same_pid_cs->file_desc); + return; + } + if (same_pid_cs->pending == pending_notifier) { - if (debug_threads) - debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, same_pid_cs->file_desc); + /* 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); set_client_state (save_client_fd); same_pid_cs->pending = none_pending; @@ -822,42 +838,6 @@ notify_clients (char *buffer) } -static void -stop_clients (client_state *current_cs) -{ - client_state *same_pid_cs = NULL; - - if (! (current_cs->pending == pending_waitee - && current_cs->last_packet_type == vStopped - && current_cs->ss->last_status_exited == have_exit)) - return; - - for (same_pid_cs = client_states.first; - same_pid_cs != NULL; - same_pid_cs = same_pid_cs->next) - { - char *out_buf = alloca (64); - - /* Insure another client is attached to the cs process */ - if (! attached_to_same_proc (current_cs, same_pid_cs)) - continue; - - same_pid_cs->ss->last_status_exited = sent_exit; - set_client_state (same_pid_cs->file_desc); - same_pid_cs->pending = none_pending; - strcpy (out_buf, "OK"); - putpkt (out_buf); - // TODO Use a better method to create this: Stop:W0;process:29e3 - sprintf (out_buf, "Stop:W0;process:%x", (unsigned)ptid_get_pid (general_thread)); - putpkt_notif (out_buf); - if (debug_threads) - debug_printf ("%s:%d %s\n", __FUNCTION__, __LINE__, out_buf); - } - set_client_state (current_cs->file_desc); - return; -} - - /* Resolve the state of client WAITEE_CS with respect to other clients connected to the same server process */ static void @@ -919,9 +899,6 @@ do_multiplexing (client_state *current_cs) return 1; } - if (current_cs->ss->last_status_exited == have_exit) - stop_clients (current_cs); - for (same_pid_cs = client_states.first; same_pid_cs != NULL; same_pid_cs = same_pid_cs->next) @@ -934,22 +911,6 @@ do_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->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: @@ -957,38 +918,12 @@ do_multiplexing (client_state *current_cs) switch (same_pid_cs->packet_type) { case /* same_pid_cs->packet_type */ vContc: - 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; @@ -1052,13 +987,6 @@ do_multiplexing (client_state *current_cs) if (!current_cs_has_bp) make_waitee_a_waiter = 1; } - else if (debug_threads) - { - if (waiter_cs->ss->current_thread_) - debug_printf ("%s:%d fd=%d no breakpoint at %#lx\n", __FUNCTION__, __LINE__, waiter_cs->file_desc, (long unsigned)(*the_target->read_pc)(get_thread_regcache (waiter_cs->ss->current_thread_, 1))); - else - debug_printf ("%s:%d fd=%d no breakpoint\n", __FUNCTION__, __LINE__, waiter_cs->file_desc); - } current_cs = set_client_state (current_cs->file_desc); } /* switch same_pid_cs->packet_type */ break; /* case vContc */ diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 74f10e0..497f73e 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -153,10 +153,6 @@ struct server_state struct inferior_list all_processes_; struct inferior_list all_threads_; struct thread_info *current_thread_; - /* If true, then GDB has requested noack mode. */ - - /* from remote-utils.c */ -// int noack_mode_; }; typedef struct server_state server_state; hooks/post-receive -- Repository for Project Archer.