gdb: replace architecture_changed with new_architecture observer
authorAndrew Burgess <aburgess@redhat.com>
Wed, 11 Oct 2023 09:30:35 +0000 (10:30 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Mon, 16 Oct 2023 09:01:22 +0000 (10:01 +0100)
This commit replaces the architecture_changed observer with a
new_architecture observer.

Currently the only user of the architecture_changed observer is the
Python code, which uses this observer to register the Python unwinder
with the architecture.

The problem is that the architecture_changed observer is triggered
from inferior::set_arch(), which only sees the inferior-wide gdbarch
value.  For targets that use thread-specific architectures, these
never trigger the architecture_changed observer, and so never have the
Python unwinder registered with them.

When it comes to unwinding GDB makes use of the frame's gdbarch, which
is based on the thread's regcache gdbarch, which is set in
get_thread_regcache to the value returned from
target_thread_architecture, which is not always the inferiors gdbarch
value, it might be a thread-specific gdbarch which has not passed
through inferior::set_arch().

The new_architecture observer will be triggered from
gdbarch_find_by_info, whenever a new gdbarch is created and
initialised.  As GDB caches and reuses gdbarch values, we should
expect to see each new architecture trigger the new_architecture
observer just once.

After this commit, targets that make use of thread-specific
architectures should be able to make use of Python unwinders.

As I don't have access to a machine that makes use of thread-specific
architectures right now, I asked Luis to confirm that an AArch64
target that uses SVE/SME can't use the Python unwinders in threads
that are using a thread-specific architectures, and he confirmed that
this is indeed the case, see this discussion:

  https://inbox.sourceware.org/gdb/87wmvsat8i.fsf@redhat.com

Tested-By: Lancelot Six <lancelot.six@amd.com>
Tested-By: Luis Machado <luis.machado@arm.com>
Reviewed-By: Luis Machado <luis.machado@arm.com>
Approved-By: Simon Marchi <simon.marchi@efficios.com>
gdb/arch-utils.c
gdb/inferior.c
gdb/observable.c
gdb/observable.h
gdb/python/py-unwind.c

index 60a50ea5b2c7335fadea3b63d4e184a450a5585d..c64584c5760c298842ca52adc20495a7621d34bd 100644 (file)
@@ -1479,6 +1479,8 @@ gdbarch_find_by_info (struct gdbarch_info info)
   if (gdbarch_debug)
     gdbarch_dump (new_gdbarch, gdb_stdlog);
 
+  gdb::observers::new_architecture.notify (new_gdbarch);
+
   return new_gdbarch;
 }
 
index efe57cceae3ec1c706c58018b2499461ddb50641..1778723863e1eeacc1291923efdeba69c7752823 100644 (file)
@@ -179,7 +179,6 @@ inferior::set_arch (gdbarch *arch)
   gdb_assert (arch != nullptr);
   gdb_assert (gdbarch_initialized_p (arch));
   m_gdbarch = arch;
-  gdb::observers::architecture_changed.notify (this, arch);
 
   process_stratum_target *proc_target = this->process_target ();
   if (proc_target != nullptr)
index 09613b2ddda301e273ac515176a9a2685bd47855..f2e65b11604d153a98eec0432d1d1f50fc5527f4 100644 (file)
@@ -52,7 +52,7 @@ DEFINE_OBSERVABLE (about_to_proceed);
 DEFINE_OBSERVABLE (breakpoint_created);
 DEFINE_OBSERVABLE (breakpoint_deleted);
 DEFINE_OBSERVABLE (breakpoint_modified);
-DEFINE_OBSERVABLE (architecture_changed);
+DEFINE_OBSERVABLE (new_architecture);
 DEFINE_OBSERVABLE (thread_ptid_changed);
 DEFINE_OBSERVABLE (inferior_added);
 DEFINE_OBSERVABLE (inferior_appeared);
index acb05e9b535cd25a0a1e0a85ec37f58859e58885..a535eedcd38f8bf4f5e0a232e3ab342494c035a7 100644 (file)
@@ -153,10 +153,9 @@ extern observable<struct breakpoint */* b */> breakpoint_deleted;
    is the modified breakpoint.  */
 extern observable<struct breakpoint */* b */> breakpoint_modified;
 
-/* INF's architecture has changed.  The argument NEWARCH is a
-   pointer to the new architecture.  */
-extern observable<inferior */* inf */, struct gdbarch */* newarch */>
-  architecture_changed;
+/* GDB has instantiated a new architecture, NEWARCH is a pointer to the new
+   architecture.  */
+extern observable<struct gdbarch */* newarch */> new_architecture;
 
 /* The thread's ptid has changed.  The OLD_PTID parameter specifies
    the old value, and NEW_PTID specifies the new value.  */
index f8b142dd52c16e53d7cdd520a3fccc8a607c77b3..ee50c51b531d60e290d42012779ad9343dc90c60 100644 (file)
@@ -945,7 +945,7 @@ static const registry<gdbarch>::key<pyuw_gdbarch_data_type> pyuw_gdbarch_data;
    intermediary.  */
 
 static void
-pyuw_on_new_gdbarch (inferior *inf, gdbarch *newarch)
+pyuw_on_new_gdbarch (gdbarch *newarch)
 {
   struct pyuw_gdbarch_data_type *data = pyuw_gdbarch_data.get (newarch);
   if (data == nullptr)
@@ -974,8 +974,7 @@ pyuw_on_new_gdbarch (inferior *inf, gdbarch *newarch)
 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
 gdbpy_initialize_unwind (void)
 {
-  gdb::observers::architecture_changed.attach (pyuw_on_new_gdbarch,
-                                              "py-unwind");
+  gdb::observers::new_architecture.attach (pyuw_on_new_gdbarch, "py-unwind");
 
   if (PyType_Ready (&pending_frame_object_type) < 0)
     return -1;