[00/16,v3] Linux extended-remote fork and exec events

Message ID 54650301.7070200@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Nov. 13, 2014, 7:14 p.m. UTC
  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(+)
  

Patch

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)
     {