From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 48103 invoked by alias); 3 May 2017 18:15:49 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 47756 invoked by uid 440); 3 May 2017 18:15:33 -0000 Date: Wed, 03 May 2017 18:15:00 -0000 Message-ID: <20170503181533.47729.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/strace: Ignore syscalls while stepping. X-Git-Refname: refs/heads/scox/strace X-Git-Reftype: branch X-Git-Oldrev: f628d97284c0aa61c9a60480140af3ee55adcd18 X-Git-Newrev: bbcfd44e17e4c85fd9dac9cc28188a8d4a32418c X-SW-Source: 2017-q2/txt/msg00017.txt.bz2 List-Id: The branch, scox/strace has been updated via bbcfd44e17e4c85fd9dac9cc28188a8d4a32418c (commit) from f628d97284c0aa61c9a60480140af3ee55adcd18 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit bbcfd44e17e4c85fd9dac9cc28188a8d4a32418c Author: Stan Cox Date: Wed May 3 14:13:29 2017 -0400 Ignore syscalls while stepping. * server.c (get_packet_type): Set displaced_step using heuristic check. Ignore syscalls during vCont;s (notify_clients): Additional TARGET_WAITKIND_IGNORE handling. * server.h (displaced_step): New. ----------------------------------------------------------------------- Summary of changes: gdb/contrib/gdbrp-dump.py | 30 ++++++++++-- gdb/gdbserver/ChangeLog | 7 +++ gdb/gdbserver/server.c | 113 +++++++++++++++++++++++++++++++------------- gdb/gdbserver/server.h | 11 ++++- 4 files changed, 120 insertions(+), 41 deletions(-) First 500 lines of diff: diff --git a/gdb/contrib/gdbrp-dump.py b/gdb/contrib/gdbrp-dump.py index 83cbbb8..cfa7689 100755 --- a/gdb/contrib/gdbrp-dump.py +++ b/gdb/contrib/gdbrp-dump.py @@ -44,6 +44,8 @@ addr_map = list() verbose = False brief = False multi_client = False +first_line = 0 +last_line = 0 # Convert arg substring starting at s ending at e to big endian @@ -505,12 +507,19 @@ def dump_server_packet(line, last_request): # Depending on verbosity, we may or may not wish to print a line -def print_this_line(aline): +def print_this_line(aline, lineno): global verbose global multi_client + global first_line + global last_line if aline.find("readahead cache") >= 0: return False + if (first_line != 0): + if (lineno < first_line): + return False + elif (lineno > last_line): + sys.exit(1) if verbose: return True if aline.find("getpkt") >= 0 or aline.find("putpkt") >= 0 or aline.find("Sending packet") >= 0: @@ -553,7 +562,7 @@ def decode_packet(aline): def usage(comment): if (len(comment) > 0): sys.stderr.write (comment) - sys.stderr.write ("Usage gdbrp-dump.py [--verbose,-v] [--no-color] [--no-lineno]\n\t[--proc-map FILE] gdbserver-logfile\n") + sys.stderr.write ("Usage gdbrp-dump.py [--verbose,-v] [--no-color] [--no-lineno]\n\t[--proc-map FILE] [--lines X:Y] gdbserver-logfile\n") sys.stderr.write ("Where --proc-map is created by the gdb 'info proc mappings' request\n\t(default /tmp/proc-map)\n") sys.stderr.write (" gdbserver-logfile is packet logging info created via gdb set debug remote or\n\tgdbserver --debug --remote-debug\n") @@ -568,6 +577,8 @@ def main(): global want_lineno global red_shift global multi_client + global first_line + global last_line if len(sys.argv) == 1: usage("") @@ -594,6 +605,12 @@ def main(): elif sys.argv[argn] == "--proc-map": argn = argn + 1 proc_map = sys.argv[argn] + elif sys.argv[argn] == "--lines": + argn = argn + 1 + lines = sys.argv[argn].split(":") + first_line = int(lines[0]) + last_line = int(lines[1]) + print "XX",first_line,last_line elif sys.argv[argn][0:1] == "-": usage("Unrecognized option " + sys.argv[argn]) sys.exit(1) @@ -638,21 +655,24 @@ def main(): ll = line.decode('ascii') except UnicodeDecodeError: ll = line - if print_this_line(ll): - if ll.find("getpkt") >= 0 or ll.find("putpkt") >= 0 or ll.find("Sending packet") >= 0 or ll.find("Packet received: ") >= 0: + if print_this_line(ll, lineno): + if ll.find("getpkt") >= 0 or ll.find("putpkt") >= 0 or ll.find("Sending packet") >= 0 or ll.find("Packet received: ") >= 0 or ll.find("Notification received:") >= 0: ll = decode_packet(ll) if len(ll) > 115: if want_lineno: print '##', red_shift, lineno, ll[0:115] + "..." else: print '##', red_shift, ll[0:115] + "..." + for i in ("Packet", "Notification"): + if (ll[115:].find(i + " received: ") >= 0): + print '##%s\t%s' % (red_shift, ll[ll.find(i + " received: "):]) else: if want_lineno: print '##', red_shift, lineno, ll, else: print '##', red_shift, ll, elif len(ll) > 126: - print '##', ll[0:126] + "..." + print '##', ll[0:126] + "...", else: print '##', ll, diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 50cffea..864390c 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,10 @@ +2017-05-03 Stan Cox + + * server.c (get_packet_type): Set displaced_step using heuristic + check. Ignore syscalls during vCont;s + (notify_clients): Additional TARGET_WAITKIND_IGNORE handling. + * server.h (displaced_step): New. + 2017-04-06 Simon Marchi * server.c (handle_v_cont): Initialize thread_resume::thread diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 22a5ea5..cd1a08e 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -87,24 +87,27 @@ static struct client_states client_states; static void handle_status (char *); /* The wait state of a client */ -enum pending_types +enum pending_types {none_pending, pending_waitee, pending_cont_waiter}; -const char *pending_types_str[] = {"not-waiting","waitee","waiter"}; +static const char *pending_types_str[] = {"not-waiting","waitee","waiter"}; /* The notification state of a nonstop client */ -enum nonstop_pending_types +enum nonstop_pending_types {no_notifier_pending, pending_notifier, pending_notified}; -const char *nonstop_pending_types_str[] = {"", "notifier", "notified"}; +static const char *nonstop_pending_types_str[] = {"", "notifier", "notified"}; /* The packet type of a client packet */ -const char *packet_types_str[] = -{"other", "vContc", "vConts","vContt","vRun", "vAttach", "Hg", "g_or_m", "Detach", +static const char *packet_types_str[] = +{"other", "vContc", "vConts","vContr","vContt","vRun", "vAttach", "Hg", "g_or_m", "Detach", "vStopped"}; -const char *waitkind_str[] = +static const char *waitkind_str[] = {"exited", "stopped", "signalled", "loaded", "forked", "vforked", "execed", "vfork-done", "syscall-entry", "syscall-exit", "spurious", "ignore", "no-history", "not-resumed", "thread-created", "thread-exited", ""}; +static const char *displaced_step_str[] = + {"", "displaced-stepping", "displaced-stepping?"}; + /* Return the current client state. */ @@ -237,6 +240,8 @@ dump_client_state (const char *function, const char *comment) const char *last_status_kind; struct regcache *regcache = NULL; CORE_ADDR pc = 0; + int sc = 0; + static const char *syscall_state[] = {"","ignoring-syscalls"}; client_states.current_cs = cs; if (cs->file_desc == -1) @@ -250,7 +255,11 @@ dump_client_state (const char *function, const char *comment) regcache = client_states.current_cs->ss->current_thread_->regcache_data; if (regcache != NULL) pc = (*the_target->read_pc) (regcache); - debug_printf (" %c%d %s pc=%#lx #=%d %s %s %s %s %s\n", + if (current_thread) + if (current_process()->syscalls_to_catch + && VEC_index (int, current_process()->syscalls_to_catch, 0) == NO_SYSCALL) + sc = 1; + debug_printf (" %c%d %s pc=%#lx #=%d %s %s %s %s %s %s %s\n", (save_cs == cs) ? '*' : ' ', cs->file_desc, target_pid_to_str (general_thread), @@ -260,7 +269,9 @@ dump_client_state (const char *function, const char *comment) packet_types_str[cs->last_packet_type], pending_types_str[cs->pending], nonstop_pending_types_str[cs->nonstop_pending], - last_status_kind); + last_status_kind, + displaced_step_str[cs->ss->displaced_step], + syscall_state[sc]); } client_states.current_cs = save_cs; } @@ -386,15 +397,31 @@ get_packet_type (client_state *cs) else return other_packet; /* We have already categorized the packet type */ - - if (cs->pending == pending_cont_waiter) - return other_packet; +// if (cs->pending == pending_cont_waiter) +// return other_packet; switch (own_packet) { + packet_types this_packet_type; case 'v': if ((strncmp (own_buffer, "vCont;c", 7) == 0)) + this_packet_type = vContc; + else if ((strncmp (own_buffer, "vCont;s", 7) == 0)) + this_packet_type = vConts; + else if ((strncmp (own_buffer, "vCont;r", 7) == 0)) + this_packet_type = vContr; + else if ((strncmp (own_buffer, "vCont;t", 7) == 0)) + this_packet_type = vContt; + else if (strncmp (own_buffer, "vRun", 4) == 0) + this_packet_type = vRun; + else if (strncmp (own_buffer, "vAttach", 4) == 0) + this_packet_type = vAttach; + else if (strncmp (own_buffer, "vStopped", 4) == 0) + this_packet_type = vStopped; + switch (this_packet_type) { + case vContc: +//s case vStopped: for (csi = client_states.first; csi != NULL; csi = csi->next) { if (attached_to_same_proc (cs, csi) && csi->syscall_op != NO_SYSCALL) @@ -404,12 +431,12 @@ get_packet_type (client_state *cs) csi->syscall_op = NO_SYSCALL; } } - return vContc; - } - else if (strncmp (own_buffer, "vCont;s", 7) == 0) - return vConts; - else if (strncmp (own_buffer, "vCont;r", 7) == 0) - { + break; + case vConts: + if (cs->ss->displaced_step == maybe_displaced_step) + cs->ss->displaced_step = in_displaced_step; + /* fall through */ + case vContr: for (csi = client_states.first; csi != NULL; csi = csi->next) { /* an in process next can be thrown off by a syscall, @@ -423,17 +450,9 @@ get_packet_type (client_state *cs) VEC_replace (int, process->syscalls_to_catch, 0, NO_SYSCALL); } } - return vConts; } - else if ((strncmp (own_buffer, "vCont;t", 7) == 0)) - return vContt; - else if (strncmp (own_buffer, "vRun", 4) == 0) - return vRun; - else if (strncmp (own_buffer, "vAttach", 4) == 0) - return vAttach; - else if (strncmp (own_buffer, "vStopped", 4) == 0) - return vStopped; - break; + return this_packet_type; + case 'H': if (own_buffer[1] == 'g') { @@ -444,10 +463,15 @@ get_packet_type (client_state *cs) break; case 'D': return Detach; + case 'G': + if (cs->non_stop_ && cs->ss->displaced_step == not_displaced_step) + cs->ss->displaced_step = maybe_displaced_step; + else if (cs->ss->displaced_step == in_displaced_step) + cs->ss->displaced_step = not_displaced_step; + // fall through case 'm': case 'M': case 'g': - case 'G': return g_or_m; }; return other_packet; @@ -651,7 +675,10 @@ setup_multiplexing (client_state *current_cs) switch (current_cs->packet_type) { case /* current_cs->packet_type */ vContc: - if (current_cs->last_packet_type != vRun) + /* Don't make a syscall client a waitee as a waiter cannot + depend on receiving a reply from it */ + if (current_cs->last_packet_type != vRun + && ! same_pid_cs->catch_syscalls) { current_cs->pending = pending_cont_waiter; same_pid_cs->pending = pending_waitee; @@ -705,9 +732,7 @@ setup_multiplexing (client_state *current_cs) default: /* 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->catch_syscalls - || current_cs->packet_type == vContc) + if (current_cs->packet_type == vContc) { dump_client_state (__FUNCTION__, "* waiting"); current_cs->last_cont_ptid = current_cs->ss->general_thread_; @@ -716,6 +741,12 @@ setup_multiplexing (client_state *current_cs) } } /* switch current_cs->last_packet_type */ default: /* fall through */ + if (current_cs->catch_syscalls && current_cs->packet_type == vContc + && current_cs->ss->displaced_step == in_displaced_step) + { + dump_client_state (__FUNCTION__, "* waiting"); + return 0; + } dump_client_state (__FUNCTION__, "* continuing"); return 1; /* Reply to packet now */ } /* switch current_cs->pending */ @@ -737,6 +768,8 @@ notify_clients (char *buffer, int have_first_notify) int make_waitee_a_waiter = 0; dump_client_state (__FUNCTION__, have_first_notify ? "first" : "not first"); + debug_printf ("%s:%d %.20s\n", __FUNCTION__, __LINE__, buffer); + if (current_cs->ss->attach_count_ == 0) return 1; @@ -761,11 +794,17 @@ notify_clients (char *buffer, int have_first_notify) same_pid_cs->nonstop_pending = pending_notifier; break; case TARGET_WAITKIND_IGNORE: - /* TODO why do syscalls sometimes arrive as ignore */ + /* TODO why does a non-syscall sometimes arrive as a syscall? */ if (! strstr (buffer, "syscall_")) break; case TARGET_WAITKIND_SYSCALL_ENTRY: case TARGET_WAITKIND_SYSCALL_RETURN: + /* TODO why do syscalls sometimes arrive as ignore */ + if (! strstr (buffer, "syscall_")) + { + same_pid_cs->nonstop_pending = none_pending; + break; + } have_syscall = 1; if (same_pid_cs->catch_syscalls) { @@ -819,6 +858,8 @@ notify_clients (char *buffer, int have_first_notify) xsnprintf (out_buf, PBUFSIZ, "%s:", notif_stop.notif_name); strcat (out_buf, buffer); set_client_state (same_pid_cs->file_desc); + if (waiter_cs->catch_syscalls) + putpkt (okay_buf); putpkt_notif (out_buf); strcpy (buffer, okay_buf); } @@ -839,6 +880,10 @@ notify_clients (char *buffer, int have_first_notify) current_cs->last_cont_ptid = current_cs->ss->general_thread_; current_cs->last_cont_waitstatus = current_cs->ss->last_status_; } + // stopped vContc waiter is handled above but ignore vContc waiter may slip through + else if (current_cs->pending == pending_cont_waiter + && (current_cs->packet_type == vContc || current_cs->packet_type == vConts)) + current_cs->pending = pending_waitee; if ((have_syscall && !current_cs->catch_syscalls) || (!have_syscall && current_cs->catch_syscalls)) diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 2e907ca..1f7ba18 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -121,6 +121,12 @@ extern int in_queued_stop_replies (ptid_t ptid); #endif /* SERVER_H */ + +enum displaced_step_type + { not_displaced_step, in_displaced_step, maybe_displaced_step }; +typedef enum displaced_step_type displaced_step_type; + + /* Description of the server state for the currently connected target. Each server_state can be associated with one or more client_state. */ @@ -128,6 +134,7 @@ extern int in_queued_stop_replies (ptid_t ptid); struct server_state { int attach_count_; + displaced_step_type displaced_step; /* From server.c */ /* The thread set with an `Hc' packet. `Hc' is deprecated in favor of `vCont'. Note the multi-process extensions made `vCont' a @@ -160,7 +167,7 @@ typedef struct server_state server_state; /* The packet type of a client packet */ enum packet_types - { other_packet, vContc, vConts, vContt, vRun, vAttach, Hg, g_or_m, Detach, vStopped }; + { other_packet, vContc, vConts, vContr, vContt, vRun, vAttach, Hg, g_or_m, Detach, vStopped }; typedef enum packet_types packet_types; /* Description of the per client state for the currently @@ -170,7 +177,7 @@ struct client_state { gdb_fildes_t file_desc; int attached_to_client; - int packet_type; + packet_types packet_type; int last_packet_type; int pending; int nonstop_pending; hooks/post-receive -- Repository for Project Archer.