public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/globalstate: Improve non-stop handling
@ 2016-03-30 14:46 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2016-03-30 14:46 UTC (permalink / raw)
To: archer-commits
The branch, scox/globalstate has been updated
via 0b038592634fba79da5353187a75028e81b6a718 (commit)
from bc4b0dbeec0fb45f9fd169cb9b3a984e9378d055 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 0b038592634fba79da5353187a75028e81b6a718
Author: Stan Cox <scox@redhat.com>
Date: Wed Mar 30 10:18:39 2016 -0400
Improve non-stop handling
* server.c (pending_types): Add pending_notifier
(dump_client_state): Dump pc and indicate current client.
(delete_client_state): Copy persistent state flags.
(resolve_waiter): Send notification for vConts
(notify_clients): New. Send notification to waiter client.
(do_multiplexing): Also consider notification state.
(process_serial_event): Remove the client breakpoint.
* notif.c (notif_push): Also notify the waiting client.
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/ChangeLog | 12 ++
gdb/gdbserver/notif.c | 1 +
gdb/gdbserver/server.c | 174 +++++++++++++++++++++++------
gdb/gdbserver/server.h | 1 +
gdb/testsuite/ChangeLog | 5 +
gdb/testsuite/gdb.server/multi-client.exp | 70 +++++-------
6 files changed, 187 insertions(+), 76 deletions(-)
First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 49c0407..f1589f9 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,15 @@
+2016-03-30 Stan Cox <scox@redhat.com>
+
+ * server.c (pending_types): Add pending_notifier
+ (dump_client_state): Dump pc and indicate current client.
+ (delete_client_state): Copy persistent state flags.
+ (resolve_waiter): Send notification for vConts
+ (notify_clients): New. Send notification to waiter client.
+ (do_multiplexing): Also consider notification state.
+ (process_serial_event): Remove the client breakpoint.
+
+ * notif.c (notif_push): Also notify the waiting client.
+
2016-02-23 Stan Cox <scox@redhat.com>
* server.c (setup_multiplexing): Add pending_step_waiter, vConts,
diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c
index 9455167..2ca0a9e 100644
--- a/gdb/gdbserver/notif.c
+++ b/gdb/gdbserver/notif.c
@@ -150,6 +150,7 @@ notif_push (struct notif_server *np, struct notif_event *new_event)
p += strlen (p);
np->write (new_event, p);
+ notify_clients (buf);
putpkt_notif (buf);
}
}
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index df1ea3c..9ae8bda 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -85,8 +85,8 @@ static struct client_states client_states;
static void handle_status (char *);
-enum pending_types {none_pending, pending_waitee, pending_cont_waiter, pending_step_waiter, pending_stop};
-char *pending_types_str[] = {"not-waiting","waitee","waiter","step-waiter","stop"};
+enum pending_types {none_pending, pending_waitee, pending_cont_waiter, pending_step_waiter, pending_stop, pending_notifier};
+char *pending_types_str[] = {"not-waiting","waitee","waiter","step-waiter","stop", "notifier"};
char *packet_types_str[] = {"other", "vContc", "vConts","vContt","vStopped","vRun", "vAttach"};
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", ""};
@@ -282,8 +282,10 @@ dump_client_state (const char *function, const char *comment)
for (cs = client_states.first; cs != NULL; cs = cs->next)
{
char *last_status_kind;
- client_states.current_cs = cs;
+ struct regcache *regcache = NULL;
+ CORE_ADDR pc = 0;
+ client_states.current_cs = cs;
if (cs->file_desc == -1)
continue;
@@ -291,12 +293,18 @@ dump_client_state (const char *function, const char *comment)
last_status_kind = waitkind_str[cs->ss->last_status_.kind];
else
last_status_kind = "";
- debug_printf ("%d %#lx(%d)/%#lx/%#lx #=%d %s %s %s %s\n",
+ if (current_thread != NULL)
+ regcache = client_states.current_cs->ss->current_thread_->regcache_data;
+ if (regcache != NULL)
+ pc = (*the_target->read_pc) (regcache);
+ if (save_cs == cs)
+ debug_printf ("*");
+ else
+ debug_printf (" ");
+ debug_printf ("%d %#lx pc=%#lx #=%d %s %s %s %s\n",
cs->file_desc,
- (long unsigned)general_thread.pid,
- (int)general_thread.pid,
- (long unsigned)cont_thread.pid,
- (long unsigned)last_ptid.pid,
+ (long unsigned)general_thread.pid,
+ (long unsigned)pc,
cs->ss->attach_count_,
packet_types_str[cs->packet_type],
packet_types_str[cs->last_packet_type],
@@ -376,9 +384,14 @@ delete_client_state (gdb_fildes_t fd)
{
ss = cs->ss;
previous_cs->next = cs->next;
- free_client_state (cs);
if (client_states.current_fd == fd)
- set_client_state (get_first_client_fd ());
+ {
+ set_client_state (get_first_client_fd ());
+ extended_protocol = cs->extended_protocol_;
+ run_once = cs->run_once_;
+ non_stop = cs->non_stop_;
+ }
+ free_client_state (cs);
cs = previous_cs;
}
if (cs->next == NULL)
@@ -446,6 +459,13 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
save_client_state = client_states.current_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 (" fd=%d %s %s", waitee_cs->file_desc, packet_types_str[waitee_cs->packet_type], pending_types_str[waitee_cs->pending]);
+ debug_printf ("\n");
+ }
switch (this_packet_type)
{
case vContc:
@@ -467,12 +487,14 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
new_notif->status = last_status;
new_notif->status.kind = TARGET_WAITKIND_STOPPED;
notif_push (¬if_stop,
- (struct notif_event *) new_notif);
+ (struct notif_event *) new_notif);
/* Explicit write of notification and remove from queue */
discard_queued_stop_replies (cs->ss->general_thread_);
notif_write_event (¬if_stop, notif_buf);
}
+ else if (last_status.kind != TARGET_WAITKIND_EXITED)
+ cs->pending = pending_notifier;
}
else if (last_status.kind != TARGET_WAITKIND_EXITED
&& cs->last_cont_ptid.pid == cs->ss->last_ptid_.pid)
@@ -498,7 +520,34 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
}
case vConts:
{
- if (last_status.kind != TARGET_WAITKIND_EXITED)
+ if (non_stop)
+ {
+ if (last_status.kind != TARGET_WAITKIND_EXITED
+ && last_status.kind != TARGET_WAITKIND_STOPPED)
+ {
+ /* Create a stop notification */
+ struct vstop_notif *new_notif;
+ char *notif_buf;
+ new_notif = XNEW (struct vstop_notif);
+ notif_buf = alloca (PBUFSIZ + 1);
+ write_ok (notif_buf);
+ putpkt (notif_buf);
+
+ new_notif->ptid = general_thread;
+ new_notif->status = last_status;
+ new_notif->status.kind = TARGET_WAITKIND_STOPPED;
+ notif_push (¬if_stop,
+ (struct notif_event *) new_notif);
+ /* Explicit write of notification and remove from queue */
+ discard_queued_stop_replies (cs->ss->general_thread_);
+
+ notif_write_event (¬if_stop, notif_buf);
+ if (last_status.kind != TARGET_WAITKIND_STOPPED)
+ cs->pending = pending_notifier;
+ }
+
+ }
+ else if (last_status.kind != TARGET_WAITKIND_EXITED)
{
/* reply to vConts with a status */
strcpy (own_buffer, "?");
@@ -506,9 +555,9 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
putpkt (own_buffer);
}
else if (last_status.kind == TARGET_WAITKIND_EXITED)
- {
+ {
putpkt (waitee_cs->own_buffer_);
- }
+ }
break;
}
case vContt:
@@ -618,11 +667,8 @@ setup_multiplexing (client_state *current_cs)
break;
/* TODO else if (current_cs->packet_type == vContt) */
case /* current_cs->packet_type */ vConts:
- if (same_pid_cs->last_packet_type != vContt)
- {
- current_cs->pending = pending_step_waiter;
- same_pid_cs->pending = pending_waitee;
- }
+ current_cs->pending = pending_step_waiter;
+ same_pid_cs->pending = pending_waitee;
}
break;
case /* same_pid_cs->pending */ pending_step_waiter:
@@ -633,9 +679,18 @@ setup_multiplexing (client_state *current_cs)
current_cs->pending = pending_cont_waiter;
resolve_waiter (same_pid_cs, current_cs);
same_pid_cs->pending = pending_waitee;
+ break;
+ }
+ case /* current_cs->packet_type */ vConts:
+ {
+ int have_waitee;
+ analyze_group (current_cs, &have_waitee);
+ /* Don't want to deadlock on everyone waiting */
+ if (current_cs->pending == pending_waitee && have_waitee)
+ current_cs->pending = pending_step_waiter;
}
}
- /* fall through for vConts case */
+ break;
case /* same_pid_cs->pending */ pending_cont_waiter:
switch (current_cs->packet_type)
{
@@ -686,7 +741,6 @@ setup_multiplexing (client_state *current_cs)
switch (current_cs->last_packet_type)
{
case vRun:
- case vStopped:
break;
default:
/* Current client is continuing and waiting so don't reply to this
@@ -707,8 +761,39 @@ setup_multiplexing (client_state *current_cs)
}
+void
+notify_clients (char *buffer)
+{
+ client_state *same_pid_cs = NULL;
+ int save_client_fd = client_states.current_fd;
+ client_state *save_client_cs = client_states.current_cs;
+ char *okay_buf = alloca (4);
+
+ write_ok (okay_buf);
+
+ for (same_pid_cs = client_states.first;
+ same_pid_cs != NULL;
+ same_pid_cs = same_pid_cs->next)
+ {
+ /* Insure another client is attached to the cs process */
+ if (! attached_to_same_proc (client_states.current_cs, same_pid_cs))
+ continue;
+ if (same_pid_cs->pending == pending_notifier)
+ {
+ if (debug_threads)
+ debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__, same_pid_cs->file_desc);
+ set_client_state (same_pid_cs->file_desc);
+ putpkt (okay_buf);
+ putpkt_notif (buffer);
+ set_client_state (save_client_fd);
+ same_pid_cs->pending = none_pending;
+ }
+ }
+}
+
+
static void
-notify_clients (client_state *current_cs)
+stop_clients (client_state *current_cs)
{
client_state *same_pid_cs = NULL;
@@ -746,7 +831,7 @@ notify_clients (client_state *current_cs)
/* Resolve the state of client WAITEE_CS with respect to other clients connected to the same server process */
static int
-do_multiplexing (client_state *current_cs, char ch)
+do_multiplexing (client_state *current_cs)
{
/***
If we have two dependent clients 4 and 7 and 4 is the current client with a
@@ -800,7 +885,7 @@ do_multiplexing (client_state *current_cs, char ch)
}
if (current_cs->ss->last_status_exited == have_exit)
- notify_clients (current_cs);
+ stop_clients (current_cs);
for (same_pid_cs = client_states.first;
same_pid_cs != NULL;
@@ -821,7 +906,6 @@ do_multiplexing (client_state *current_cs, char ch)
{
case /* same_pid_cs->packet_type */ vContc:
prepare_to_access_memory ();
-
if (current_cs->packet_type == vContc
&& (current_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_ENTRY
|| current_cs->ss->last_status_.kind == TARGET_WAITKIND_SYSCALL_RETURN))
@@ -859,10 +943,15 @@ do_multiplexing (client_state *current_cs, char ch)
struct thread_info *thread;
CORE_ADDR pc;
if (non_stop)
- thread = current_thread;
+ {
+ thread = current_thread;
+ regcache = get_thread_regcache (thread, 1);
+ }
else
- thread = find_thread_ptid (last_ptid);
- regcache = get_thread_regcache (thread, 1);
+ {
+ thread = find_thread_ptid (last_ptid);
+ regcache = get_thread_regcache (thread, 1);
+ }
pc = (*the_target->read_pc) (regcache);
current_cs_has_bp = has_client_breakpoint_at (pc);
waiter_cs = set_client_state (same_pid_cs->file_desc);
@@ -875,10 +964,11 @@ do_multiplexing (client_state *current_cs, char ch)
{
/* Belatedly reply to the waiter client */
resolve_waiter (waiter_cs, current_cs);
- current_cs->pending = none_pending;
+ if (current_cs->pending != pending_notifier)
+ current_cs->pending = none_pending;
if (!current_cs_has_bp)
waiter_cs->pending = pending_waitee;
- else
+ else if (waiter_cs->pending != pending_notifier)
waiter_cs->pending = none_pending;
/* If the waitee did not reach the breakpoint then it needs to wait */
if (!current_cs_has_bp)
@@ -892,7 +982,6 @@ do_multiplexing (client_state *current_cs, char ch)
debug_printf ("%s:%d fd=%d no breakpoint\n", __FUNCTION__, __LINE__, waiter_cs->file_desc);
}
current_cs = set_client_state (current_cs->file_desc);
-
done_accessing_memory ();
} /* switch same_pid_cs->packet_type */
break; /* case vContc */
@@ -900,20 +989,22 @@ do_multiplexing (client_state *current_cs, char ch)
case /* same_pid_cs->pending */ pending_step_waiter:
waiter_cs = set_client_state (same_pid_cs->file_desc);
if (debug_threads)
- debug_printf ("%s:%d resolving %d/%d %s", __FUNCTION__, __LINE__, current_cs->file_desc,same_pid_cs->pending,packet_types_str[current_cs->packet_type]);
- if (current_cs->packet_type == vConts
- || current_cs->packet_type == vContc)
+ debug_printf ("%s:%d resolving %d %s %s\n", __FUNCTION__, __LINE__, current_cs->file_desc,pending_types_str[same_pid_cs->pending],packet_types_str[current_cs->packet_type]);
+ if (current_cs->packet_type == vContc
+ || (current_cs->packet_type == vConts && !non_stop))
{
resolve_waiter (waiter_cs, current_cs);
current_cs->pending = same_pid_cs->pending = none_pending;
}
+ else if (current_cs->packet_type == vConts && non_stop)
+ same_pid_cs->pending = pending_notifier;
current_cs = set_client_state (current_cs->file_desc);
} /* switch same_pid_cs->pending */
}
if (make_waitee_a_waiter && current_cs->packet_type == vContc)
{
- /* The packet will be replied to later in do_multiplexing */
+ /* The packet will be replied to later in do_multiplexing */
current_cs->pending = pending_cont_waiter;
dump_client_state (__FUNCTION__, "return 0");
current_cs->last_cont_ptid = current_cs->ss->general_thread_;
@@ -5094,7 +5185,12 @@ process_serial_event (void)
}
}
else
- res = delete_gdb_breakpoint (type, addr, kind);
+ {
+ res = delete_gdb_breakpoint (type, addr, kind);
+ if (res != 0 && has_client_breakpoint_at (addr))
+ res = 0;
+ delete_client_breakpoint (addr);
+ }
if (res == 0)
write_ok (own_buffer);
@@ -5202,7 +5298,7 @@ process_serial_event (void)
break;
}
- if (! do_multiplexing (cs, ch))
+ if (! do_multiplexing (cs))
return 0;
if (new_packet_len != -1)
@@ -5262,6 +5358,10 @@ handle_target_event (int err, gdb_client_data client_data)
last_ptid = mywait (minus_one_ptid, &last_status,
TARGET_WNOHANG, 1);
+ if (debug_threads)
+ debug_printf ("%s fd=%d queue=%d %s\n", __FUNCTION__, client_states.current_fd, notif_stop.queue->head == NULL ? 0 : 1,
+ waitkind_str[last_status.kind]);
+
if (last_status.kind == TARGET_WAITKIND_NO_RESUMED)
{
if (gdb_connected () && report_no_resumed)
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index fdf51a0..675231c 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -84,6 +84,7 @@ typedef int gdb_fildes_t;
/* Functions from server.c. */
extern int handle_serial_event (int err, gdb_client_data client_data);
extern int handle_target_event (int err, gdb_client_data client_data);
+extern void notify_clients (char *buffer);
/* Get rid of the currently pending stop replies that match PTID. */
extern void discard_queued_stop_replies (ptid_t ptid);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c0b2623..6c898ea 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-30 Stan Cox <scox@redhat.com>
+
+ * gdb.server/multi-client.exp (start_client) Add testpath parameter.
+ (cleanup_server_and_clients) New.
+
2016-02-23 Stan Cox <scox@redhat.com>
* gdb.server/multi-client.exp: Add next, strace, and pthreads tests.
diff --git a/gdb/testsuite/gdb.server/multi-client.exp b/gdb/testsuite/gdb.server/multi-client.exp
index d61c024..5effe48 100644
--- a/gdb/testsuite/gdb.server/multi-client.exp
+++ b/gdb/testsuite/gdb.server/multi-client.exp
@@ -23,10 +23,6 @@ set srcfile wrapper.c
global srcdir subdir
set testpath [pwd]/$subdir/$testfile
-set testfile2 server-kill
-set srcfile2 server-kill.c
-set testpath2 [pwd]/$subdir/$testfile2
-
set testfile3 catch-syscall
set srcfile3 ../gdb.base/catch-syscall.c
set testpath3 [pwd]/$subdir/$testfile3
@@ -38,9 +34,6 @@ set testpath4 [pwd]/$subdir/$testfile4
if { [prepare_for_testing $test $testfile $srcfile debug] } {
return -1
}
-if {[build_executable $test $testfile2 $srcfile2 debug] == -1} {
- return -1
-}
if {[build_executable $test $testfile3 $srcfile3 debug] == -1} {
return -1
}
@@ -79,8 +72,9 @@ proc start_gdbserver { } {
return $res
}
-proc start_client { N ATTACH_FLAGS } {
+proc start_client { N TESTPATH FLAGS ATTACH_FLAGS } {
global test gdb_spawn_id GDB MULTI_GDBFLAGS
+ set MULTI_GDBFLAGS "$FLAGS -iex \"file $TESTPATH\" -iex \"set remotetimeout 600\" -iex \"target extended-remote localhost:65432\" -iex \"set remote exec-file $TESTPATH\" --silent --data-directory=[file dirname $GDB]/data-directory"
set res [remote_spawn host "$GDB $MULTI_GDBFLAGS $ATTACH_FLAGS [host_info gdb_opts] -iex \"set prompt (client $N gdb) \""]
sleep 1
set ok 0
@@ -101,7 +95,7 @@ proc start_client { N ATTACH_FLAGS } {
}
proc start_strace { ATTACH_FLAGS } {
- global test gdb_spawn_id MULTI_GDBFLAGS
+ global test gdb_spawn_id
set STRACE [auto_execok strace]
verbose "strace is $STRACE $ATTACH_FLAGS"
set res [remote_spawn host "$STRACE $ATTACH_FLAGS"]
@@ -173,12 +167,22 @@ proc gdb_command { CLIENT COMMAND RESPONSE COMMENT } {
}
}
+proc cleanup_server_and_clients { } {
+ global gdb_server_spawn_id
+ global gdb_client1_spawn_id
+ global gdb_client2_spawn_id
+ global gdb_client3_spawn_id
+ exec kill -KILL [exp_pid -i $gdb_server_spawn_id]
+ exec kill -KILL [exp_pid -i $gdb_client1_spawn_id]
+ exec kill -KILL [exp_pid -i $gdb_client2_spawn_id]
+ exec kill -KILL [exp_pid -i $gdb_client3_spawn_id]
+}
+
verbose "##### Test coordination of three clients doing break/continue"
set gdb_server_spawn_id [start_gdbserver]
-set MULTI_GDBFLAGS "-iex \"file $testpath\" -iex \"set remotetimeout 600\" -iex \"target extended-remote localhost:65432\" -iex \"set remote exec-file $testpath\" --silent --data-directory=[file dirname $GDB]/data-directory"
-set gdb_client1_spawn_id [start_client 1 ""]
+set gdb_client1_spawn_id [start_client 1 $testpath "" ""]
gdb_command 1 "b getenv" "Breakpoint 1 at" "b getenv"
@@ -186,9 +190,9 @@ gdb_command 1 "run" "Breakpoint 1," "hit b getenv"
set target_pid [get_target_pid wrapper]
-set gdb_client2_spawn_id [start_client 2 "-iex \"attach $target_pid\""]
+set gdb_client2_spawn_id [start_client 2 $testpath "" "-iex \"attach $target_pid\""]
-set gdb_client3_spawn_id [start_client 3 "-iex \"attach $target_pid\""]
+set gdb_client3_spawn_id [start_client 3 $testpath "" "-iex \"attach $target_pid\""]
gdb_command 2 "b marker" "Breakpoint 1 at" "b marker"
@@ -234,13 +238,13 @@ if { $ok == 1 } {
fail "$test client exited"
}
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-03-30 14:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-30 14:46 [SCM] scox/globalstate: Improve non-stop handling 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).