From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 68660 invoked by alias); 23 Oct 2016 19:10:51 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 68637 invoked by uid 440); 23 Oct 2016 19:10:50 -0000 Date: Sun, 23 Oct 2016 19:10:00 -0000 Message-ID: <20161023191050.68609.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/strace: * server.c (set_client_state): Transfer initial commandline info. (setup_multiplexing): syscall client cannot be waitee if it may not continue. (notify_client): Organize similarly to do_multiplexing. Handle syscall point similar to break point. (do_multiplexing): Likewise. (handle_general_set): Support strace -f and strace -e * server.h (FOLLOW_CHILD): New for strace -f * linux-low.c (gdb_catch_this_syscall_p): Support strace -f and strace -e * gdb.server/multi-client.exp: Add threaded test. X-Git-Refname: refs/heads/scox/strace X-Git-Reftype: branch X-Git-Oldrev: 29ed0969c6a127c58777f9c2a91f5dabc3dab909 X-Git-Newrev: cf6f2ca1c40cfcbd5078edf12bf2ed887e8a7bfe X-SW-Source: 2016-q4/txt/msg00000.txt.bz2 List-Id: The branch, scox/strace has been updated via cf6f2ca1c40cfcbd5078edf12bf2ed887e8a7bfe (commit) from 29ed0969c6a127c58777f9c2a91f5dabc3dab909 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit cf6f2ca1c40cfcbd5078edf12bf2ed887e8a7bfe Author: Stan Cox Date: Sun Oct 23 15:08:53 2016 -0400 * server.c (set_client_state): Transfer initial commandline info. (setup_multiplexing): syscall client cannot be waitee if it may not continue. (notify_client): Organize similarly to do_multiplexing. Handle syscall point similar to break point. (do_multiplexing): Likewise. (handle_general_set): Support strace -f and strace -e * server.h (FOLLOW_CHILD): New for strace -f * linux-low.c (gdb_catch_this_syscall_p): Support strace -f and strace -e * gdb.server/multi-client.exp: Add threaded test. ----------------------------------------------------------------------- Summary of changes: gdb/gdbserver/ChangeLog | 15 ++ gdb/gdbserver/linux-low.c | 32 ++- gdb/gdbserver/remote-utils.c | 10 +- gdb/gdbserver/server.c | 379 ++++++++++++++--------------- gdb/gdbserver/server.h | 3 + gdb/testsuite/ChangeLog | 6 +- gdb/testsuite/gdb.server/multi-client.exp | 186 ++++++++++++-- 7 files changed, 395 insertions(+), 236 deletions(-) First 500 lines of diff: diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 6dd1329..1e32722 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,18 @@ +2016-10-23 Stan Cox + + * server.c (set_client_state): Transfer initial commandline info. + (setup_multiplexing): syscall client cannot be waitee if it may + not continue. + (notify_client): Organize similarly to do_multiplexing. Handle + syscall point similar to break point. + (do_multiplexing): Likewise. + (handle_general_set): Support strace -f and strace -e + + * server.h (FOLLOW_CHILD): New for strace -f + + * linux-low.c (gdb_catch_this_syscall_p): Support strace -f and + strace -e + 2016-09-14 Stan Cox * server.c: Improve formatting and comments. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index ec0481c..1adb781 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -74,9 +74,8 @@ /* Some targets did not define these ptrace constants from the start, so gdbserver defines them locally here. In the future, these may be removed after they are added to asm/ptrace.h. */ -#if !(defined(PT_TEXT_ADDR) \ - || defined(PT_DATA_ADDR) \ - || defined(PT_TEXT_END_ADDR)) +/* This macro change is to circumvent an emacs semantic bug */ +#if !(defined(PT_TEXT_ADDR) || defined(PT_DATA_ADDR) || defined(PT_TEXT_END_ADDR)) #if defined(__mcoldfire__) /* These are still undefined in 3.10 kernels. */ #define PT_TEXT_ADDR 49*4 @@ -3192,20 +3191,35 @@ 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) == 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++) - if (iter == sysno) - return 1; - + switch (iter) + { + case FOLLOW_CHILD: + break; + case ANY_SYSCALL: + return 1; + break; + default: + if (iter == sysno) + return 1; + } + return 0; } diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index c9ae589..ed9ecbd 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -1479,6 +1479,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb) int len; struct sym_cache *sym; struct process_info *proc; + client_state *cs = get_client_state(); proc = current_process (); @@ -1503,7 +1504,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb) return -1; /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ - len = getpkt (remote_desc, own_buffer); + len = getpkt (cs->file_desc, own_buffer); if (len < 0) return -1; @@ -1541,7 +1542,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb) } else break; - len = getpkt (remote_desc, own_buffer); + len = getpkt (cs->file_desc, own_buffer); if (len < 0) return -1; } @@ -1590,6 +1591,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc) { int len; ULONGEST written = 0; + client_state *cs = get_client_state(); /* Send the request. */ strcpy (own_buffer, "qRelocInsn:"); @@ -1599,7 +1601,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc) return -1; /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ - len = getpkt (remote_desc, own_buffer); + len = getpkt (cs->file_desc, own_buffer); if (len < 0) return -1; @@ -1642,7 +1644,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc) free (mem_buffer); if (putpkt (own_buffer) < 0) return -1; - len = getpkt (remote_desc, own_buffer); + len = getpkt (cs->file_desc, own_buffer); if (len < 0) return -1; } diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index b03a4e6..cada601 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -121,10 +121,10 @@ get_client_state (void) client_state * set_client_state (gdb_fildes_t fd) { -/* States: - * fd = -1 add initial client state - * fd = F add client state for fd F - */ + /* States: + * fd = -1 add initial client state + * fd = F add client state for fd F + */ client_state *csidx, *cs; @@ -176,10 +176,10 @@ set_client_state (gdb_fildes_t fd) cs->ss->last_ptid_ = null_ptid; cs->ss->last_status_.kind = TARGET_WAITKIND_IGNORE; cs->ss->current_thread_ = NULL; - cs->ss->all_processes_.head = NULL; - cs->ss->all_processes_.tail = NULL; - cs->ss->all_threads_.head = NULL; - cs->ss->all_threads_.tail = NULL; + client_states.first->ss->all_processes_.head = NULL; + client_states.first->ss->all_processes_.tail = NULL; + client_states.first->ss->all_threads_.head = NULL; + client_states.first->ss->all_threads_.tail = NULL; client_states.current_fd = fd; csidx->next = client_states.current_cs; return cs; @@ -253,9 +253,9 @@ dump_client_state (const char *function, const char *comment) debug_printf (" *"); else debug_printf (" "); - debug_printf ("%d %lu pc=%#lx #=%d %s %s %s %s %s\n", + debug_printf ("%d %s pc=%#lx #=%d %s %s %s %s %s\n", cs->file_desc, - (long unsigned)general_thread.pid, + target_pid_to_str (general_thread), (long unsigned)pc, cs->ss->attach_count_, packet_types_str[cs->packet_type], @@ -424,17 +424,6 @@ get_packet_type (client_state *cs) } -/* Is this client waiting on another client? */ - -static int -is_waiter (client_state *cs) -{ - return ((cs->packet_type == vContc - || cs->packet_type == vConts) - && (cs->pending == pending_cont_waiter)); -} - - static int queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg); static void @@ -446,9 +435,9 @@ vstop_notif_reply (struct notif_event *event, char *own_buf) } struct notif_server notif_stop = -{ - "vStopped", "Stop", NULL, vstop_notif_reply, -}; + { + "vStopped", "Stop", NULL, vstop_notif_reply, + }; /* Belatedly reply to client CS, which is waiting on a packet reply. */ @@ -463,17 +452,17 @@ resolve_waiter (client_state *cs, client_state *waitee_cs) set_client_state (cs->file_desc); if (debug_threads) { - debug_printf ("%s:%d fd=%d %s %s", __FUNCTION__, __LINE__, - cs->file_desc, packet_types_str[this_packet_type], - pending_types_str[cs->pending]); - if (waitee_cs) + debug_printf ("%s:%d fd=%d %s %s", __FUNCTION__, __LINE__, + cs->file_desc, packet_types_str[this_packet_type], + pending_types_str[cs->pending]); + if (waitee_cs) debug_printf (" fd=%d %s %s", waitee_cs->file_desc, packet_types_str[waitee_cs->packet_type], pending_types_str[waitee_cs->pending]); - debug_printf ("\n"); - } + debug_printf ("\n"); + } switch (this_packet_type) - { + { case vContc: { strcpy (own_buffer, "?"); @@ -503,57 +492,57 @@ resolve_waiter (client_state *cs, client_state *waitee_cs) } break; } - case vConts: - { - if (non_stop) - { - if (last_status.kind != TARGET_WAITKIND_EXITED) - cs->nonstop_pending = pending_notifier; - } - else if (last_status.kind != TARGET_WAITKIND_EXITED) - { - putpkt (waitee_cs->own_buffer_); - } - else if (last_status.kind == TARGET_WAITKIND_EXITED) - { - putpkt (waitee_cs->own_buffer_); - } - break; - } - case vContt: - { - if (last_status.kind != TARGET_WAITKIND_EXITED - && last_status.kind != TARGET_WAITKIND_STOPPED) - { - char *notif_buf, *out_buf; - notif_buf = (char*) alloca (PBUFSIZ + 1); - write_ok (notif_buf); - putpkt (notif_buf); - - find_inferior (&all_threads, queue_stop_reply_callback, NULL); - notif_write_event (¬if_stop, notif_buf); - out_buf = (char*) alloca (strlen (notif_buf) + 8); - /* TODO Use Defined notif constant */ - xsnprintf (out_buf, PBUFSIZ, "%s:", notif_stop.notif_name); - 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); - } - break; - } - case vRun: - { - strcpy (own_buffer, "OK"); - putpkt (own_buffer); + case vConts: + { + if (non_stop) + { + if (last_status.kind != TARGET_WAITKIND_EXITED) + cs->nonstop_pending = pending_notifier; + } + else if (last_status.kind != TARGET_WAITKIND_EXITED) + { + putpkt (waitee_cs->own_buffer_); + } + else if (last_status.kind == TARGET_WAITKIND_EXITED) + { + putpkt (waitee_cs->own_buffer_); + } + break; + } + case vContt: + { + if (last_status.kind != TARGET_WAITKIND_EXITED + && last_status.kind != TARGET_WAITKIND_STOPPED) + { + char *notif_buf, *out_buf; + notif_buf = (char*) alloca (PBUFSIZ + 1); + write_ok (notif_buf); + putpkt (notif_buf); + + find_inferior (&all_threads, queue_stop_reply_callback, NULL); + notif_write_event (¬if_stop, notif_buf); + out_buf = (char*) alloca (strlen (notif_buf) + 8); + /* TODO Use Defined notif constant */ + xsnprintf (out_buf, PBUFSIZ, "%s:", notif_stop.notif_name); + 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); + } + break; + } + case vRun: + { + strcpy (own_buffer, "OK"); + putpkt (own_buffer); + break; + } + default: break; - } - default: - break; - }; + }; set_client_state (save_client_state->file_desc); } @@ -586,22 +575,22 @@ static int setup_multiplexing (client_state *current_cs) { /*** - If we have two independent clients 4 and 7 and 4 is the current - client with a vConts packet then we change both client's state - BEFORE - packet_type last_packet_type pending last_status_.kind - 4 vConts vConts not-waiting stopped - 7 other vAttach not-waiting stopped - AFTER - 4 vConts vConts step-waiter stopped - 7 other vAttach waitee stopped - - If we have two dependent clients 4 and 7 and 4 is the current client with a - vContc packet then we change nothing here. process_serial_event will handle - the vContc then do_multiplexing will decide to either continue with client 4 - or wakeup and continue with client 7. - 4 vContc vConts waitee stopped - 7 vContc vContc waiter stopped + If we have two independent clients 4 and 7 and 4 is the current + client with a vConts packet then we change both client's state + BEFORE + packet_type last_packet_type pending last_status_.kind + 4 vConts vConts not-waiting stopped + 7 other vAttach not-waiting stopped + AFTER + 4 vConts vConts step-waiter stopped + 7 other vAttach waitee stopped + + If we have two dependent clients 4 and 7 and 4 is the current client with a + vContc packet then we change nothing here. process_serial_event will handle + the vContc then do_multiplexing will decide to either continue with client 4 + or wakeup and continue with client 7. + 4 vContc vConts waitee stopped + 7 vContc vContc waiter stopped ***/ client_state *same_pid_cs = NULL; @@ -638,7 +627,7 @@ setup_multiplexing (client_state *current_cs) case /* same_pid_cs->pending */ pending_cont_waiter: switch (current_cs->packet_type) { - /* Current client is continuing and found another waiter client */ + /* Current client is continuing and found another waiter client */ case /* current_cs->packet_type */ vContc: { int have_waitee; @@ -654,10 +643,13 @@ setup_multiplexing (client_state *current_cs) case /* same_pid_cs->pending */ pending_waitee: switch (current_cs->packet_type) { - /* Current client is continuing and found another waitee client */ + /* Current client is continuing and found another waitee client */ case /* current_cs->packet_type */ vContc: { - current_cs->pending = pending_cont_waiter; + /* Don't make a syscall client a waitee as a waiter cannot + depend on receiving a reply from it */ + if (! same_pid_cs->catch_syscalls) + current_cs->pending = pending_cont_waiter; } break; } @@ -695,19 +687,21 @@ setup_multiplexing (client_state *current_cs) } -/* Send a notification to a pending client. - Called via the handle_target_event notification mechanism. */ +/* Send a notification to a pending client. Called via the + handle_target_event notification mechanism. This is a non-stop + variation of do_multiplexing */ int notify_clients (char *buffer, int have_first_notify) { client_state *same_pid_cs = NULL; int save_client_fd = client_states.current_fd; - client_state *save_client_cs = client_states.current_cs; + client_state *current_cs = client_states.current_cs; char *okay_buf = (char*) alloca (4); int have_syscall = 0; + int make_waitee_a_waiter = 0; - dump_client_state (__FUNCTION__, ""); + dump_client_state (__FUNCTION__, have_first_notify ? "first" : "not first"); write_ok (okay_buf); @@ -715,69 +709,86 @@ notify_clients (char *buffer, int have_first_notify) same_pid_cs != NULL; same_pid_cs = same_pid_cs->next) { + client_state *waiter_cs = NULL; + /* Is this a client attached to the same process? */ if (! attached_to_same_proc (client_states.current_cs, same_pid_cs)) continue; switch (last_status.kind) - { + { + case TARGET_WAITKIND_EXITED: + waiter_cs = set_client_state (same_pid_cs->file_desc); + make_waitee_a_waiter = 1; + same_pid_cs->nonstop_pending = pending_notifier; + break; case TARGET_WAITKIND_SYSCALL_ENTRY: case TARGET_WAITKIND_SYSCALL_RETURN: + /* current client continued and got a syscall + which another client was waiting for */ have_syscall = 1; - 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 1; - case TARGET_WAITKIND_STOPPED: - /* pending client will also want a notify */ - if (save_client_cs->packet_type == vStopped) + if (same_pid_cs->catch_syscalls) { + waiter_cs = set_client_state (same_pid_cs->file_desc); + make_waitee_a_waiter = 1; same_pid_cs->nonstop_pending = pending_notifier; } - + break; + case TARGET_WAITKIND_STOPPED: default: - /* syscall clients only need to see a syscall packet */ - if (save_client_cs->catch_syscalls) + /* we want only syscalls but got something else */ + if (current_cs->catch_syscalls) { - set_client_state (same_pid_cs->file_desc); - return 1; + waiter_cs = set_client_state (same_pid_cs->file_desc); + make_waitee_a_waiter = 1; + same_pid_cs->nonstop_pending = pending_notifier; } + break; } + debug_printf ("%s:%d after switch first=%d have_syscall=%d notifier=%d/%d\n", __FUNCTION__, __LINE__, have_first_notify, have_syscall, current_cs->nonstop_pending, same_pid_cs->nonstop_pending); /* syscall continue was erroneously caught by by a non syscall client */ - if (save_client_cs->packet_type == other_packet - && same_pid_cs->catch_syscalls) - return 0; + dump_client_state ("",""); hooks/post-receive -- Repository for Project Archer.