Re: [PATCH 00/16 v3] Linux extended-remote fork and exec events

Pedro Alves
2014-11-13T19:14:17Z

On 10/31/2014 11:28 PM, Don Breazeal wrote:
>
> - gdb.threads/thread-execl.exp gives a couple of failures related to
> scheduler locking. As with the previous item, after spending some
> time on this I concluded that pursuing it further now would be
> feature-creep, and that this should be tracked with a bug report.

These really are problems with the series that should be fixed.

The next problem I saw with thread-execl.exp after fixing the stale
threads issue was that the inferior would sometimes crash after execing.

Funny, because I hit this similar problem on the linux-nat.c target
when working on all-stop-on-top-of-non-stop (but I haven't posted a
fix for the linux-nat.c side yet).

From 3ee65262da9d72ab6efd97aed538f1f436436c3d Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Thu, 13 Nov 2014 17:52:38 +0000
Subject: [PATCH] stale thread state and regcaches when a non-leader thread
execs

---
gdb/gdbserver/linux-low.c | 12 ++++++++++++
gdb/remote.c | 10 ++++++++++
2 files changed, 22 insertions(+)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 316b302..e4e4231 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -546,6 +546,18 @@ handle_extended_wait (struct lwp_info *event_child, int *wstatp)
lwpid_of (event_thr));
}

+ /* This may have been a non-leader thread execing, while the
+ previous incarnation of the leader was stopped (e.g., we
+ resumed the thread that execs with schedlock on). Clear the
+ now stale register cache. */
+ get_thread_regcache (event_thr, 0)->registers_valid = 0;
+ /* ... and mark the thread as resumed, as otherwise we'd
+ consider that GDB had explicitly interrupted it. */
+ event_thr->last_resume_kind = resume_continue;
+ /* and clear this so we don't confuse things like decr_pc
+ adjustment. */
+ event_child->stepping = 0;
+
event_child->waitstatus.kind = TARGET_WAITKIND_EXECD;
event_child->waitstatus.value.execd_pathname
= xstrdup (linux_pid_to_exec_file (NULL, lwpid_of (event_thr)));
diff --git a/gdb/remote.c b/gdb/remote.c
index 9623bd6..c529a37 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5973,6 +5973,16 @@ process_stop_reply (struct stop_reply *stop_reply,
if (ptid_equal (ptid, null_ptid))
ptid = inferior_ptid;

+ if (status->kind == TARGET_WAITKIND_EXECD)
+ {
+ /* This may have been a non-leader thread execing, while the
+ previous incarnation of the leader was stopped (e.g., we
+ resumed the thread that execs with schedlock on). Clear the
+ now stale register cache before re-filling with the expedite
+ registers. */
+ registers_changed_ptid (ptid);
+ }
+
if (status->kind != TARGET_WAITKIND_EXITED
&& status->kind != TARGET_WAITKIND_SIGNALLED)
{
--
1.9.3