From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 73819 invoked by alias); 4 Sep 2015 17:38:47 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 73401 invoked by uid 440); 4 Sep 2015 17:38:47 -0000 Date: Fri, 04 Sep 2015 17:38:00 -0000 Message-ID: <20150904173847.73345.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/dyninst: Don't special case vRun; improve multi-client.exp X-Git-Refname: refs/heads/scox/dyninst X-Git-Reftype: branch X-Git-Oldrev: a8a28945db8a7c3323bd15b89f4eb66bd71d72bf X-Git-Newrev: f1c3c9074983eb3bec03ccba3ea489c2313d26a8 X-SW-Source: 2015-q3/txt/msg00043.txt.bz2 List-Id: The branch, scox/dyninst has been updated via f1c3c9074983eb3bec03ccba3ea489c2313d26a8 (commit) from a8a28945db8a7c3323bd15b89f4eb66bd71d72bf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit f1c3c9074983eb3bec03ccba3ea489c2313d26a8 Author: Stan Cox Date: Fri Sep 4 13:36:01 2015 -0400 Don't special case vRun; improve multi-client.exp * server.c (get_packet_type, ignore_packet): Split from normalize_packet. (setup_multiplexing, do_multiplexing): Improve waitee/waiter distinction. Don't special case vRun. (handle_v_run): Likewise. * server.h (packet_types): Add packet_types * multi-client.exp: Use the existing wrapper.c as the testcase. ----------------------------------------------------------------------- Summary of changes: gdb/gdbserver/ChangeLog | 53 ++++++- gdb/gdbserver/server.c | 271 +++++++++++++---------------- gdb/gdbserver/server.h | 7 +- gdb/testsuite/ChangeLog | 4 + gdb/testsuite/gdb.server/multi-client.exp | 89 ++++++---- 5 files changed, 234 insertions(+), 190 deletions(-) First 500 lines of diff: diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 27c9be3..1072ebf 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,7 +1,54 @@ -2015-05-15 Pedro Alves - - * target.h (target_handle_new_gdb_connection): Rewrite using if - wrapped in do/while. +2015-09-04 Stan Cox + + * server.c (get_packet_type, ignore_packet): Split from normalize_packet. + (setup_multiplexing, do_multiplexing): Improve waitee/waiter. Don't special case vRun. + (handle_v_run): Likewise. + * server.h (packet_types): Add packet_types + +2015-08-25 Stan Cox + + * server.c (add_client_by_pid, add_client_by_exe, get_first_client_fd): + Renamed from add_client_state, attach_client_state, count_client_state + (have_multiple_clients): New + (setup_multiplexing, do_multiplexing): Moved from process_serial_event. + * testsuite/gdb.server/multi-client.exp: New. + +2015-08-11 Stan Cox + + * dyninst-low.cc (dump_processes): Use for_each_client_state. + (delete_lwp_callback): New. + (dyninst_request_interrupt): Insure we found the process. + (dyninst_insert_point): Set break_info. + (dyninst_remove_point): Remove break_info. + +2015-07-10 Stan Cox + + * dyninst-low.cc (EventSet.remove): New, to remove a procs events. + (EventSet.get): Ignore terminated procs. + (is_fork): New, to determine if there is a fork event. + (dump_events, dump_processes): Debugging tools. + (lwp_info) Renamed to match usage in linux-low.c. + (dyninst_add_lwp) Link lwp_info to both gdb and dyninst lwp structs. + (dyninst_resume) For now, just handle one resume request. + (dyninst_wait_1) Add separate cases for singlestep and fork events. + (dyninst_mourn, dyninst_fetch_registers, dyninst_store_registers) + (dyninst_write_pc, dyninst_write_memory, dyninst_insert_point) + (dyninst_remove_point) Insure process is active. + * dyninst-low.h (breakpoint, breakpoint_len): Opcode the arch uses + for a breakpoint trap. + * dyninst-x86=low.cc (dyninst_x86_fill_gregset) + (dyninst_x86_store_gregset): Allow for smaller dyninst regset size. + * mem-break.c (has_client_breakpoint_at): Given multiple clients + for the same process does clientA have a break at location addr. + (insert_shadow_memory): Allows shadow memory use by a backend that + manages its own breakpoints. + * server.c (free_client_state): Free all client state memory. + (count_client_state) Return the file desc for an active client in + case an existing client has terminated. + (add_client_breakpoint, delete_client_breakpoint) As per has_client_breakpoint_at. + (normalize_packet): Improve handling for multiple clients for the same process. + (process_serial_event): Likewise. Save the original getpkt contents in in_buf. + * server.h (struct client_breakpoint): New, as per has_client_breakpoint_at 2015-05-14 Joel Brobecker diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 072b87c..f34fe84 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -202,15 +202,6 @@ add_client_by_exe (client_state *cs, char *executable) new_executable = xmalloc (strlen (executable) + 1); strcpy (new_executable, executable); cs->executable = new_executable; - - if (csi != NULL) - { - free_server_state (cs->ss); /* reuse the matched server state */ - cs->ss = csi->ss; - cs->ss->attach_count += 1; - return cs; - } - return NULL; } @@ -268,7 +259,7 @@ set_client_state (gdb_fildes_t fd) *new_csidx = *csidx; new_csidx->ss = new_server_state (); *new_csidx->ss = *csidx->ss; - new_csidx->normalized_packet = '\0'; + new_csidx->normalized_packet = other_packet; new_csidx->executable = NULL; new_csidx->in_buf = NULL; new_csidx->wrapper_argv = NULL; @@ -442,76 +433,67 @@ static const char lcd_request [127][127] = { enum pending_types {none_pending=0, pending_waitee=1, pending_cont_waiter=2,pending_step_waiter=3}; -/* inspect the packet in own_buf and normalize it to a corresponding gdb request for the - not ignore_packet case, or output a packet that will cause the packet to be ignored for - the ignore_packet case. */ - -int -normalize_packet (client_state *cs, int ignore_packet) +packet_types +get_packet_type (client_state *cs) { char own_packet; - int ignored_packet = 0; if (cs->in_buf) own_packet = cs->in_buf[0]; else - return 0; + return other_packet; /* If we are just categorizing to a normalized gdb request and we have already done so then return */ - if (!ignore_packet && (cs->pending == pending_cont_waiter - || cs->pending == pending_step_waiter)) - return 0; + if (cs->pending == pending_cont_waiter || cs->pending == pending_step_waiter) + return other_packet; switch (own_packet) { case 'v': if ((strncmp (cs->in_buf, "vCont;c", 7) == 0)) - if (ignore_packet) + return vContc; + else if ((strncmp (cs->in_buf, "vCont;r", 7) == 0) || (strncmp (cs->in_buf, "vCont;s", 7) == 0)) + return vConts; + else if (strncmp (cs->in_buf, "vRun", 4) == 0) + return vRun; + break; + }; + return other_packet; +} + +/* output a packet that will cause the packet to be ignored. */ + +void +ignore_packet (client_state *cs) +{ + switch (cs->normalized_packet) + { + case vContc: + { + if (cs->ss->last_status.kind != TARGET_WAITKIND_EXITED) { strcpy (cs->own_buf, "?"); handle_status (cs->own_buf); putpkt (cs->own_buf); - ignored_packet = 1; } - else - cs->normalized_packet = 'c'; - else if ((strncmp (cs->in_buf, "vCont;r", 7) == 0) || (strncmp (cs->in_buf, "vCont;s", 7) == 0)) - if (ignore_packet) + break; + } + case vConts: + { + if (cs->ss->last_status.kind != TARGET_WAITKIND_EXITED) { strcpy (cs->own_buf, "?"); handle_status (cs->own_buf); putpkt (cs->own_buf); - ignored_packet = 1; } - else - cs->normalized_packet = 's'; - else if (strncmp (cs->in_buf, "vRun", 4) == 0) - { - if (ignore_packet) - { - strcpy (cs->own_buf, "OK"); - putpkt (cs->own_buf); - ignored_packet = 1; - } - else - cs->normalized_packet = 'r'; - } - - break; - - default: - if (ignore_packet) - { - strcpy (cs->own_buf, "OK"); - putpkt (cs->own_buf); - ignored_packet = 1; - } - else - cs->normalized_packet = '\0'; + break; + } + case vRun: + { + strcpy (cs->own_buf, "OK"); + putpkt (cs->own_buf); + break; + } }; - if (ignore_packet && ignored_packet) - return 1; - else - return 0; } @@ -530,19 +512,21 @@ setup_multiplexing (client_state *cs, char *ch) /* find this client's pending type */ if (!csidx->pending) { - if (cs->normalized_packet == 'c') + if (cs->normalized_packet == vContc) { - cs->pending = pending_cont_waiter; - if (cs->last_normalized_packet != 'r') - csidx->pending = pending_waitee; + if (cs->last_normalized_packet != vRun) + { + cs->pending = pending_cont_waiter; + csidx->pending = pending_waitee; + } if (debug_threads) debug_printf ("%s:%d pending check set %d %d\n", __FUNCTION__, __LINE__,csidx->file_desc,csidx->pending); } - else if (cs->normalized_packet == 's') + else if (cs->normalized_packet == vConts) { cs->pending = pending_step_waiter; - if (cs->last_normalized_packet != 'r') + if (cs->last_normalized_packet != vRun) csidx->pending = pending_waitee; if (debug_threads) debug_printf ("%s:%d pending check set %d %d\n", __FUNCTION__, __LINE__,csidx->file_desc,csidx->pending); @@ -554,98 +538,95 @@ setup_multiplexing (client_state *cs, char *ch) debug_printf ("%s:%d pending check %d waiter=%d\n", __FUNCTION__, __LINE__,cs->file_desc,cs->pending); if (cs->pending == pending_cont_waiter) { - if (cs->last_normalized_packet != 'r') + if (cs->last_normalized_packet != vRun) return 0; - // A client is running a process that is already being run by another client - else - { - *ch = '?'; - cs->pending = none_pending; - cs->last_normalized_packet = '\0'; - } } return 1; } int -do_multiplexing (client_state *cs, char ch) -{ /* Handle pending type */ +do_multiplexing (client_state *waitee_cs, char ch) +{ client_state *csidx = NULL; - if (cs->normalized_packet != '\0') - cs->last_normalized_packet = cs->normalized_packet; + if (waitee_cs->normalized_packet != other_packet) + waitee_cs->last_normalized_packet = waitee_cs->normalized_packet; + + if (waitee_cs->normalized_packet != vContc || waitee_cs->pending != pending_waitee) + return 1; + for (csidx = client_states.first; csidx != NULL; csidx = csidx->next) { - if (cs->normalized_packet == 'c' && cs->pending == pending_waitee - && csidx->pending == pending_cont_waiter) - { - /* TODO Don't assume only 2 clients connected to a process - has waitee/waiter been resolved? */ - if (csidx->normalized_packet == 'c') - { - char save_ch = ch; - client_state *save_cs = cs; - int waitee_has_bp, waiter_has_bp; - if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED) - { - waitee_has_bp = 1; - waiter_has_bp = 1; - } - else - { - waitee_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1))); - cs = set_client_state (csidx->file_desc); - waiter_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1))); - if (debug_threads) - debug_printf ("%s:%d pc=%#lx waitee=%d has bp=%d waiter=%d has bp=%d\n", __FUNCTION__, __LINE__, (long unsigned)(*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1)), cs->file_desc, waitee_has_bp, save_cs->file_desc, waiter_has_bp); - } - if (waiter_has_bp) - { - /* fake the reply to the waiter client */ - if (debug_threads) - debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc); - normalize_packet (cs, 1); - csidx->pending = none_pending; - save_cs->pending = none_pending; - if (!waitee_has_bp) - cs->pending = pending_waitee; - } - else if (debug_threads) - { - if (cs->ss->current_thread) - debug_printf ("%s:%d fd=%d not normalized; no breakpoint at %#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)(*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1))); - else - debug_printf ("%s:%d fd=%d not normalized; no breakpoint\n", __FUNCTION__, __LINE__, cs->file_desc); - } - ch = save_ch; - cs = set_client_state (save_cs->file_desc); - if (!waitee_has_bp) - { - cs->pending = pending_cont_waiter; - return 0; - } - } - else if (cs->normalized_packet == 's' && csidx->normalized_packet == 's') - { - char save_ch = ch; - client_state *save_cs = cs; - cs = set_client_state (csidx->file_desc); - /* fake the reply to the waiter client */ - debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc); - normalize_packet (cs, 1); - csidx->pending = none_pending; - save_cs->pending = none_pending; - ch = save_ch; - cs = set_client_state (save_cs->file_desc); - } - } + if (csidx->pending == pending_cont_waiter) + { + /* Has waitee/waiter been resolved? */ + if (csidx->normalized_packet == vContc) + { + client_state *waiter_cs; + char save_ch = ch; + int waitee_has_bp, waiter_has_bp; + if (waitee_cs->ss->last_status.kind == TARGET_WAITKIND_EXITED) + { + waiter_cs = set_client_state (csidx->file_desc); + waitee_has_bp = 1; + waiter_has_bp = 1; + } + else + { + waitee_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (waitee_cs->ss->current_thread, 1))); + waiter_cs = set_client_state (csidx->file_desc); + waiter_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (waiter_cs->ss->current_thread, 1))); + if (debug_threads) + debug_printf ("%s:%d pc=%#lx waitee=%d has bp=%d waiter=%d has bp=%d\n", __FUNCTION__, __LINE__, (long unsigned)(*the_target->read_pc)(get_thread_regcache (waiter_cs->ss->current_thread, 1)), waitee_cs->file_desc, waitee_has_bp, waiter_cs->file_desc, waiter_has_bp); + } + if (waiter_has_bp) + { + /* fake the reply to the waiter client */ + if (debug_threads) + debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, waiter_cs->file_desc); + ignore_packet (waiter_cs); + if (waiter_cs->ss->last_status.kind == TARGET_WAITKIND_EXITED) + putpkt (waitee_cs->own_buf); // Send the waitee W reply to vCont to the waiter + csidx->pending = none_pending; + waitee_cs->pending = none_pending; + if (!waitee_has_bp) + waiter_cs->pending = pending_waitee; + } + else if (debug_threads) + { + if (waiter_cs->ss->current_thread) + debug_printf ("%s:%d fd=%d not normalized; 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 not normalized; no breakpoint\n", __FUNCTION__, __LINE__, waiter_cs->file_desc); + } + ch = save_ch; + waitee_cs = set_client_state (waitee_cs->file_desc); + if (!waitee_has_bp) + { + waitee_cs->pending = pending_cont_waiter; + return 0; + } + } + else if (waitee_cs->normalized_packet == vConts && csidx->normalized_packet == vConts) + { + char save_ch = ch; + client_state *waiter_cs; + waiter_cs = set_client_state (csidx->file_desc); + /* fake the reply to the waiter client */ + debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, waiter_cs->file_desc); + ignore_packet (waiter_cs); + csidx->pending = none_pending; + waitee_cs->pending = none_pending; + ch = save_ch; + waitee_cs = set_client_state (waitee_cs->file_desc); + } + } } return 1; } - /* Post a stop reply to the stop reply queue. */ static void @@ -1639,7 +1620,7 @@ handle_monitor_command (char *mon, char *own_buf) client_state *save_cs = cs; cs = set_client_state (csidx->file_desc); /* fake the reply to the waiter client */ - normalize_packet (cs, 1); + ignore_packet (cs); csidx->pending = none_pending; set_client_state (save_cs->file_desc); } @@ -3282,12 +3263,6 @@ handle_v_run (char *own_buf) freeargv (cs->program_argv); cs->program_argv = new_argv; - if (add_client_by_exe (cs, new_argv[0])) - { - if (debug_threads) - debug_printf ("%s:%d returning 0 for vAttach;%d\n",__FUNCTION__, __LINE__, ptid_get_pid (cs->ss->last_ptid)); - return 0; - } start_inferior (cs->program_argv); if (cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED) @@ -3647,7 +3622,7 @@ handle_status (char *own_buf) /* we are detaching a multi attached client */ if (debug_threads > 1) debug_printf ("%s:%d before prepare_resume_reply call %d %d\n", __FUNCTION__, __LINE__, cs->ss->attach_count, cs->packet); - if (thread != NULL && !(cs->packet == 'D' && cs->ss->attach_count > 0)) + if (thread != NULL) { struct thread_info *tp = (struct thread_info *) thread; @@ -4347,7 +4322,7 @@ process_serial_event (gdb_client_data client_data) cs->packet = ch; - normalize_packet (cs, 0); + cs->normalized_packet = get_packet_type (cs); if (! setup_multiplexing (cs, &ch)) return 0; diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index e8861aa..799964f 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -143,6 +143,9 @@ struct client_breakpoint struct client_breakpoint *next; }; +enum packet_types { other_packet = 0, vContc = 1, vConts = 2, vRun = 3 }; +typedef enum packet_types packet_types; + struct client_state { // inferior_list is not used for this since it is indexed by ptid_t and this @@ -152,8 +155,8 @@ struct client_state char *own_buf; char *in_buf; char packet; - char normalized_packet; // if own_buf == "OK" - char last_normalized_packet; + int normalized_packet; // if own_buf == "OK" + int last_normalized_packet; int pending; // following were in server.c // --once: Exit after the first connection has closed. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3a947eb..707a54f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-09-04 Stan Cox + + * multi-client.exp: New multi client gdbserver test. + 2015-05-20 Andrew Burgess * lib/gdb.exp (skip_tui_tests): New proc. diff --git a/gdb/testsuite/gdb.server/multi-client.exp b/gdb/testsuite/gdb.server/multi-client.exp index 9b46202..83347b0 100644 --- a/gdb/testsuite/gdb.server/multi-client.exp +++ b/gdb/testsuite/gdb.server/multi-client.exp @@ -16,51 +16,56 @@ load_lib gdbserver-support.exp set test "multi-client" +# wrapper.c is used as the test exec-file +set testfile wrapper +set srcfile wrapper.c +global srcdir subdir +set testpath [pwd]/$subdir/$testfile +if { [prepare_for_testing multi-client.exp $testfile $srcfile debug] } { + return -1 +} hooks/post-receive -- Repository for Project Archer.