aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2020-08-07 10:26:45 -0600
committerTom Tromey <tromey@adacore.com>2020-08-07 10:26:47 -0600
commit592f9bd76a1a9888eb95eff24048c12ca2c1f332 (patch)
tree3776100ad95d663b7b1a4f0690b3cc0aa35bac48 /gdb
parent39e2018a4e83522fef595d079c880c9097d70228 (diff)
downloadgdb-592f9bd76a1a9888eb95eff24048c12ca2c1f332.zip
gdb-592f9bd76a1a9888eb95eff24048c12ca2c1f332.tar.gz
gdb-592f9bd76a1a9888eb95eff24048c12ca2c1f332.tar.bz2
Fetch registers from correct thread in ravenscar-thread.c
Fabien also noticed that gdb would not report a stop correctly when using Ravenscar. This patch fixes the bug by making a few changes: * ravenscar_thread_target::wait now updates the inferior ptid before updating the thread list. This ensures that a new thread is correctly associated with the underlying CPU. * The fetch_registers, store_registers, and prepare_to_store methods now save and restore the regcache's ptid before doing the operation on the underlying live thread. This ensures that gdb informs the remote of a thread it knows about, as opposed to using a Ravenscar thread, which probably will not be recognized. gdb/ChangeLog 2020-08-07 Tom Tromey <tromey@adacore.com> * ravenscar-thread.c (ravenscar_thread_target::wait): Call update_inferior_ptid before update_thread_list. (temporarily_change_regcache_ptid): New class. (ravenscar_thread_target::fetch_registers) (ravenscar_thread_target::store_registers) (ravenscar_thread_target::prepare_to_store): Use base thread when forwarding operation.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/ravenscar-thread.c85
2 files changed, 77 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0d443a8..640fb39 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2020-08-07 Tom Tromey <tromey@adacore.com>
+ * ravenscar-thread.c (ravenscar_thread_target::wait): Call
+ update_inferior_ptid before update_thread_list.
+ (temporarily_change_regcache_ptid): New class.
+ (ravenscar_thread_target::fetch_registers)
+ (ravenscar_thread_target::store_registers)
+ (ravenscar_thread_target::prepare_to_store): Use base thread when
+ forwarding operation.
+
+2020-08-07 Tom Tromey <tromey@adacore.com>
+
* ravenscar-thread.c (ravenscar_thread_target::resume): Handle
"is_pid" case.
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index 91f0920..459e5ea 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -457,20 +457,55 @@ ravenscar_thread_target::pid_to_str (ptid_t ptid)
return string_printf ("Ravenscar Thread %#x", (int) ptid.tid ());
}
+/* Temporarily set the ptid of a regcache to some other value. When
+ this object is destroyed, the regcache's original ptid is
+ restored. */
+
+class temporarily_change_regcache_ptid
+{
+public:
+
+ temporarily_change_regcache_ptid (struct regcache *regcache, ptid_t new_ptid)
+ : m_regcache (regcache),
+ m_save_ptid (regcache->ptid ())
+ {
+ m_regcache->set_ptid (new_ptid);
+ }
+
+ ~temporarily_change_regcache_ptid ()
+ {
+ m_regcache->set_ptid (m_save_ptid);
+ }
+
+private:
+
+ /* The regcache. */
+ struct regcache *m_regcache;
+ /* The saved ptid. */
+ ptid_t m_save_ptid;
+};
+
void
ravenscar_thread_target::fetch_registers (struct regcache *regcache, int regnum)
{
ptid_t ptid = regcache->ptid ();
- if (runtime_initialized ()
- && is_ravenscar_task (ptid)
- && !task_is_currently_active (ptid))
+ if (runtime_initialized () && is_ravenscar_task (ptid))
{
- struct gdbarch *gdbarch = regcache->arch ();
- struct ravenscar_arch_ops *arch_ops
- = gdbarch_ravenscar_ops (gdbarch);
+ if (task_is_currently_active (ptid))
+ {
+ ptid_t base = get_base_thread_from_ravenscar_task (ptid);
+ temporarily_change_regcache_ptid changer (regcache, base);
+ beneath ()->fetch_registers (regcache, regnum);
+ }
+ else
+ {
+ struct gdbarch *gdbarch = regcache->arch ();
+ struct ravenscar_arch_ops *arch_ops
+ = gdbarch_ravenscar_ops (gdbarch);
- arch_ops->fetch_registers (regcache, regnum);
+ arch_ops->fetch_registers (regcache, regnum);
+ }
}
else
beneath ()->fetch_registers (regcache, regnum);
@@ -482,15 +517,22 @@ ravenscar_thread_target::store_registers (struct regcache *regcache,
{
ptid_t ptid = regcache->ptid ();
- if (runtime_initialized ()
- && is_ravenscar_task (ptid)
- && !task_is_currently_active (ptid))
+ if (runtime_initialized () && is_ravenscar_task (ptid))
{
- struct gdbarch *gdbarch = regcache->arch ();
- struct ravenscar_arch_ops *arch_ops
- = gdbarch_ravenscar_ops (gdbarch);
+ if (task_is_currently_active (ptid))
+ {
+ ptid_t base = get_base_thread_from_ravenscar_task (ptid);
+ temporarily_change_regcache_ptid changer (regcache, base);
+ beneath ()->store_registers (regcache, regnum);
+ }
+ else
+ {
+ struct gdbarch *gdbarch = regcache->arch ();
+ struct ravenscar_arch_ops *arch_ops
+ = gdbarch_ravenscar_ops (gdbarch);
- arch_ops->store_registers (regcache, regnum);
+ arch_ops->store_registers (regcache, regnum);
+ }
}
else
beneath ()->store_registers (regcache, regnum);
@@ -501,11 +543,18 @@ ravenscar_thread_target::prepare_to_store (struct regcache *regcache)
{
ptid_t ptid = regcache->ptid ();
- if (runtime_initialized ()
- && is_ravenscar_task (ptid)
- && !task_is_currently_active (ptid))
+ if (runtime_initialized () && is_ravenscar_task (ptid))
{
- /* Nothing. */
+ if (task_is_currently_active (ptid))
+ {
+ ptid_t base = get_base_thread_from_ravenscar_task (ptid);
+ temporarily_change_regcache_ptid changer (regcache, base);
+ beneath ()->prepare_to_store (regcache);
+ }
+ else
+ {
+ /* Nothing. */
+ }
}
else
beneath ()->prepare_to_store (regcache);