From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1702 invoked by alias); 2 Jan 2017 23:36:25 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 1677 invoked by uid 440); 2 Jan 2017 23:36:25 -0000 Date: Mon, 02 Jan 2017 23:36:00 -0000 Message-ID: <20170102233625.1650.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/strace: Send both stopped thread and general thread to syscall clients. X-Git-Refname: refs/heads/scox/strace X-Git-Reftype: branch X-Git-Oldrev: 2020670cfec28db64144a510f0bac8a32b99a8f6 X-Git-Newrev: d9fbfc03d6950e913fb10b3ccdfd70499b7f331b X-SW-Source: 2017-q1/txt/msg00004.txt.bz2 List-Id: The branch, scox/strace has been updated via d9fbfc03d6950e913fb10b3ccdfd70499b7f331b (commit) from 2020670cfec28db64144a510f0bac8a32b99a8f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit d9fbfc03d6950e913fb10b3ccdfd70499b7f331b Author: Stan Cox Date: Mon Jan 2 18:30:07 2017 -0500 Send both stopped thread and general thread to syscall clients. * server.c (handle_general_set): Revert to original catch syscall protocol. * server.h: Likewise. * linux-low.c (gdb_catch_this_syscall_p): Likewise. * remote-utils.c (prepare_resume_reply): Include general thread as a stop reply component for syscalls. ----------------------------------------------------------------------- Summary of changes: gdb/contrib/gdbrp-dump.py | 92 ++++++++++++-------- gdb/gdbserver/ChangeLog | 9 ++ gdb/gdbserver/linux-low.c | 28 ++----- gdb/gdbserver/remote-utils.c | 10 ++ gdb/gdbserver/server.c | 27 +++--- gdb/gdbserver/server.h | 5 +- gdb/testsuite/ChangeLog | 5 + gdb/testsuite/gdb.server/multi-client.exp | 138 ++++++++++++++++++++++------ gdb/testsuite/gdb.server/strace-threads.c | 70 ++++++-------- 9 files changed, 238 insertions(+), 146 deletions(-) First 500 lines of diff: diff --git a/gdb/contrib/gdbrp-dump.py b/gdb/contrib/gdbrp-dump.py index f2d1d46..400ff5f 100755 --- a/gdb/contrib/gdbrp-dump.py +++ b/gdb/contrib/gdbrp-dump.py @@ -32,6 +32,7 @@ import sys import binascii import chardet import re +import os.path from commands import getstatusoutput executable = "" @@ -41,6 +42,7 @@ want_lineno = True hexchars = (['a', 'c', 'b', 'e', 'd', 'f', '1', '0', '3', '2', '5', '4', '7', '6', '9', '8']) addr_map = list() verbose = False +brief = False multi_client = False # Convert arg substring starting at s ending at e to big endian @@ -79,7 +81,7 @@ def print_rip(regval, eol): base_addr = 0 base_obj = "" - if len(regval) == 0: + if len(regval) == 0 or regval[0:2] == 'xx': return address = int(str('0x' + regval), 16) if len(executable) > 0: @@ -114,10 +116,13 @@ def print_rip(regval, eol): def print_register(regno, field, begin, end): regval = big_endian(field, begin, end) - if register(regno) == "rip": - print_rip(regval, False) - else: - print register(regno), "=", regval, + try: + if register(regno) == "rip": + print_rip(regval, False) + else: + print register(regno), "=", regval, + except ValueError: + print "XX" def dump_registers(arg): @@ -151,6 +156,27 @@ def dump_memory(arg): print prefix, print +def print_pid(arg): + ti = 0 + if arg.find("/") > 0: + arg = arg[0:arg.find("/")].rstrip() + pid = arg.split(".") + if len(pid) > 1: + if pid[0][0:1] == "p": + print "pid=%s/%d" % (pid[0][1:], int(pid[0][1:], 16)), + elif pid[0] == "-1": + print "pid=*", + else: + print "pid=%s/%d" % (pid[0][0:],int("0x" + pid[0][0:], 16)), + ti = 1 + if pid[ti] == "-1": + print " tid=*", + else: + try: + print " tid=%s/%d" % (pid[ti], int(pid[ti],16)) + except ValueError: + print " xxx" + # Dump the packet that is sent from the client def dump_client_packet(line): @@ -339,6 +365,10 @@ def dump_client_packet(line): if argidx == len(args): break arg = args[argidx] + if arg.find("/") > 0: + arg = arg[0:arg.find("/")].rstrip() + else: + arg = arg.rstrip() if a == "action": print a, "=", if arg[0] == "c": @@ -353,28 +383,9 @@ def dump_client_packet(line): argidx += 1 print "range step %s-%s" % (arg[1:], args[argidx]), elif a == "thread-id": - pid = arg.split(".") - if len(pid) > 1: - print "pid =", - if pid[0][0:1] == "p": - print pid[0][0:], - elif pid[0] == "-1": - print "*", - else: - print "pid =", int("0x" + pid[0][0:], 16), - ti = 1 - else: - ti = 0 - print "tid =", - if pid[ti] == "-1": - print "*", - else: - print pid[ti], + print "Thread:" , + print_pid (arg) elif a == "symbol-name": - if arg.find("/") > 0: - arg = arg[0:arg.find("/")].rstrip() - else: - arg = arg.rstrip() if len(arg) > 1: idx = len(arg) if idx % 2 > 0: @@ -390,8 +401,6 @@ def dump_client_packet(line): else: if arg.find("...") > 0: arg = arg[0:arg.find("...")] - if arg.find("/") > 0: - arg = arg[0:arg.find("/")] print a, "=", arg, argidx = argidx + 1 print @@ -432,14 +441,17 @@ def dump_server_packet(line, last_request): if args[0][0] == 'T' or args[0][0] == 'S': if args[0][0] == 'S': args[0] = args[0][5:] - print dsp_prefix, "packet reply: signal=", signal(int(args[0][1:3], 16)), + try: + print dsp_prefix, "packet reply: signal=", signal(int(args[0][1:3], 16)), + except ValueError: + pass subargs = args[0].split(':') print print dsp_prefix, try: if args[0][3:5] == "sy": - status, text = getstatusoutput('grep " ' + str(int(subargs[1], 16)) + '$" /usr/include/asm/unistd_64.h') - print text[8:], + status, text = getstatusoutput('grep "_NR_.* ' + str(int(subargs[1], 16)) + '$" /usr/include/asm/unistd_64.h') + print text[text.find("#define ")+8:], elif args[0][3:5] == "wa": print "watch =", subargs[1], else: @@ -457,8 +469,9 @@ def dump_server_packet(line, last_request): continue subargs = a.split(':') if subargs[0] == "thread": - print dsp_prefix, "Thread:", subargs[1], - else: + print dsp_prefix,"Thread:" , + print_pid (subargs[1]) + elif a[0:2].isdigit(): print dsp_prefix, print_register(a[0:2], subargs[1], 0, 0) print @@ -487,15 +500,15 @@ def print_this_line(aline): if aline.find("readahead cache") >= 0: return False + if verbose: + return True if aline.find("getpkt") >= 0 or aline.find("putpkt") >= 0 or aline.find("Sending packet") >= 0: return True - if multi_client: + if multi_client and not brief: if re.match("^ *[*]*[0-9][0-9]* LWP", aline, flags=0): return True elif re.match("^ *\*\* client state", aline, flags=0): return True - elif verbose: - return True return False # Decode a packet. The encoding scheme is described in: info gdb.info 'remote p' overview @@ -533,6 +546,7 @@ def usage(comment): def main(): global verbose + global brief global want_lineno global red_shift global multi_client @@ -548,11 +562,13 @@ def main(): argn = 1 logname = "" - proc_map = "/tmp/proc-map" + proc_map = "" while argn < len(sys.argv): if sys.argv[argn] == "--verbose" or sys.argv[argn] == "-v": verbose = True + elif sys.argv[argn] == "--brief" or sys.argv[argn] == "-b": + brief = True elif sys.argv[argn] == "--no-color": red_shift = "" elif sys.argv[argn] == "--no-lineno": @@ -569,6 +585,8 @@ def main(): # Create address mapping file + if len(proc_map) == 0: + proc_map = os.path.dirname (logname) + "/client-map" try: logfile = open(proc_map) for line in logfile: diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 1e32722..bcb6681 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,12 @@ +2017-01-02 Stan Cox + + * server.c (handle_general_set): Revert to original catch syscall + protocol. + * server.h: Likewise. + * linux-low.c (gdb_catch_this_syscall_p): Likewise. + * remote-utils.c (prepare_resume_reply): Include general thread as + a stop reply component for syscalls. + 2016-10-23 Stan Cox * server.c (set_client_state): Transfer initial commandline info. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 9262e4b..d771182 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -3191,37 +3191,23 @@ gdb_catch_this_syscall_p (struct lwp_info *event_child) int sysno; struct thread_info *thread = get_lwp_thread (event_child); struct process_info *proc = get_thread_process (thread); - ptid thread_ptid = thread_to_gdb_id (thread); - ptid proc_ptid = ptid_of (proc); if (VEC_empty (int, proc->syscalls_to_catch)) return 0; + if (VEC_index (int, proc->syscalls_to_catch, 0) == NO_SYSCALL) return 0; + + if (VEC_index (int, proc->syscalls_to_catch, 0) == ANY_SYSCALL) + return 1; get_syscall_trapinfo (event_child, &sysno); - - /* (FOLLOW,SYSCALL1,...,SYSCALLN) OR (FOLLOW,ANY) OR (ANY) */ - if (VEC_index (int, proc->syscalls_to_catch, 0) != FOLLOW_CHILD - && (ptid_get_pid (thread_ptid) != ptid_get_pid (proc_ptid) - || ptid_get_lwp (thread_ptid) != ptid_get_pid (thread_ptid))) - return 0; - for (i = 0; VEC_iterate (int, proc->syscalls_to_catch, i, iter); i++) - switch (iter) - { - case FOLLOW_CHILD: - break; - case ANY_SYSCALL: - return 1; - break; - default: - if (iter == sysno) - return 1; - } - + if (iter == sysno) + return 1; + return 0; } diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index ed9ecbd..f1064bb 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -1271,6 +1271,16 @@ prepare_resume_reply (char *buf, ptid_t ptid, buf = write_ptid (buf, ptid); strcat (buf, ";"); buf += strlen (buf); + if (non_stop + && (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY + || status->kind == TARGET_WAITKIND_SYSCALL_RETURN)) + { + sprintf (buf, "thread:"); + buf += strlen (buf); + buf = write_ptid (buf, general_thread); + strcat (buf, ";"); + buf += strlen (buf); + } core = target_core_of_thread (ptid); diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 050c629..f79ce10 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -167,6 +167,7 @@ set_client_state (gdb_fildes_t fd) cs->packet_type = other_packet; cs->last_packet_type = other_packet; cs->pending = none_pending; + cs->syscall_op = NO_SYSCALL; cs->own_buffer_ = (char*) xmalloc (PBUFSIZ + 1); client_states.current_cs = cs; cs->ss->attach_count_ = 0; @@ -396,18 +397,18 @@ get_packet_type (client_state *cs) { for (csi = client_states.first; csi != NULL; csi = csi->next) { - if (attached_to_same_proc (cs, csi) && csi->syscall_op) + if (attached_to_same_proc (cs, csi) && csi->syscall_op != NO_SYSCALL) { process = current_process (); VEC_replace (int, process->syscalls_to_catch, 0, csi->syscall_op); - csi->syscall_op = 0; + 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) + else if (strncmp (own_buffer, "vCont;r", 7) == 0) { for (csi = client_states.first; csi != NULL; csi = csi->next) { @@ -436,7 +437,7 @@ get_packet_type (client_state *cs) case 'H': if (own_buffer[1] == 'g') { - client_states.current_cs->new_general_thread = + client_states.current_cs->new_general_thread = read_ptid (&own_buffer[2], NULL); return Hg; } @@ -470,7 +471,7 @@ struct notif_server notif_stop = static void resolve_waiter (client_state *cs, client_state *waitee_cs) { - enum packet_types this_packet_type = + enum packet_types this_packet_type = (enum packet_types)((cs->packet_type) ? cs->packet_type : cs->last_packet_type); client_state *save_client_state; @@ -753,6 +754,10 @@ notify_clients (char *buffer, int have_first_notify) make_waitee_a_waiter = 1; same_pid_cs->nonstop_pending = pending_notifier; break; + case TARGET_WAITKIND_IGNORE: + /* TODO why do syscalls sometimes arrive as ignore */ + if (! strstr (buffer, "syscall_")) + break; case TARGET_WAITKIND_SYSCALL_ENTRY: case TARGET_WAITKIND_SYSCALL_RETURN: have_syscall = 1; @@ -1483,8 +1488,6 @@ handle_general_set (char *own_buf) enabled = 0; else if (p[0] == '1' && (p[1] == ';' || p[1] == '\0')) enabled = 1; - else if (p[0] == '2' && (p[1] == ';' || p[1] == '\0')) - enabled = 2; else { fprintf (stderr, "Unknown catch-syscalls mode requested: %s\n", @@ -1496,12 +1499,8 @@ handle_general_set (char *own_buf) process = current_process (); VEC_truncate (int, process->syscalls_to_catch, 0); - /* (FOLLOW,SYSCALL1,...,SYSCALLN) (FOLLOW,ANY) (ANY) */ - switch (enabled) + if (enabled) { - case 2: - VEC_safe_push (int, process->syscalls_to_catch, FOLLOW_CHILD); - case 1: p += 1; if (*p == ';') { @@ -5273,7 +5272,7 @@ process_serial_event (void) } if (! do_multiplexing (get_client_state())) - return 0; + return 0; if (new_packet_len != -1) putpkt_binary (own_buffer, new_packet_len); @@ -5440,7 +5439,7 @@ handle_target_event (int err, gdb_client_data client_data) } } else - push_stop_notification (last_ptid, &last_status); + push_stop_notification (last_ptid, &last_status); } /* Be sure to not change the selected thread behind GDB's back. diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 4726831..18cd43c 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -113,10 +113,7 @@ extern void discard_queued_stop_replies (ptid_t ptid); #define ANY_SYSCALL (-2) /* Trace child processes created via fork or clone. */ -#define FOLLOW_CHILD (-3) - -/* Trace child processes created via fork or clone. */ -#define NO_SYSCALL (-4) +#define NO_SYSCALL (-3) #endif /* SERVER_H */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ac24021..6781df6 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-01-02 Stan Cox + + * gdb.server/multi-client.exp: Add multithreaded test. + * gdb.server/strace-threads.c: Likewise. + 2016-10-23 Stan Cox * gdb.server/multi-client.exp: Add threaded test. diff --git a/gdb/testsuite/gdb.server/multi-client.exp b/gdb/testsuite/gdb.server/multi-client.exp index c82db90..e1689fc 100644 --- a/gdb/testsuite/gdb.server/multi-client.exp +++ b/gdb/testsuite/gdb.server/multi-client.exp @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -exp_internal 1 +# exp_internal 1 load_lib gdbserver-support.exp load_lib prelink-support.exp @@ -111,7 +111,7 @@ proc get_target_pid { target_exec } { perror "$test Failed to get pid of target process. $expect_out(buffer)" return 1 } - verbose "XXX spawn_id $res" + close -i $res set pgrep_spawn_id $res return $target_pid } @@ -130,12 +130,12 @@ proc gdb_command { COMMAND RESPONSE COMMENT } { } if {$ok == 1} { pass "$COMMENT" - } else { - fail "$COMMENT" } } } +set clean_idx 0 + proc cleanup_server_and_clients { } { global strace_spawn_id global server_spawn_id @@ -143,28 +143,24 @@ proc cleanup_server_and_clients { } { global gdb_spawn_id global inferior_spawn_id global pgrep_spawn_id + global clean_idx - catch {verbose "BBB strace [exp_pid -i $strace_spawn_id]"} - catch {verbose "BBB gdb [exp_pid -i $gdb_spawn_id]"} - catch {verbose "BBB inferior [exp_pid -i $inferior_spawn_id]"} - catch {verbose "BBB pgrep [exp_pid -i $pgrep_spawn_id]"} - + incr clean_idx + close_gdbserver catch {exec kill -KILL [exp_pid -i $strace_spawn_id]} catch {exec kill -KILL [exp_pid -i $gdb_spawn_id]} catch {exec kill -KILL [exp_pid -i $inferior_spawn_id]} catch {exec kill -KILL [exp_pid -i $pgrep_spawn_id]} if { $target_pid > 1 } {catch {exec kill -KILL $target_pid}} - close_gdbserver gdb_exit - system "ps" "-fax" "--width=320" "-o" "pid,ppid,lwp,rss,time,cmd" ">|" "/tmp/,x" } +foreach NONSTOP { off on } { + #------------------------------------------------------- verbose "##### Test coordination of a gdb client and an strace client" -foreach NONSTOP { off on } { - set res [gdbserver_start "--multi" ""] sleep 2 hooks/post-receive -- Repository for Project Archer.