public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [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.
@ 2016-10-23 19:10 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2016-10-23 19:10 UTC (permalink / raw)
To: archer-commits
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 <scox@redhat.com>
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 <scox@redhat.com>
+
+ * 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 <scox@redhat.com>
* 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.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-10-23 19:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-23 19:10 [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 scox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).