[v2,01/11] s390: Remove duplicate checks for cached gdbarch at init

Message ID 20171205122859.2919-2-prudo@linux.vnet.ibm.com
State New, archived
Headers

Commit Message

Philipp Rudo Dec. 5, 2017, 12:28 p.m. UTC
  When initializing the gdbarch there is a check whether an appropriate
gdbarch already exists in the gdbarch_list.  If any of the checks fails
this would lead to a different target description.  However
gdbarch_list_lookup_by_info already checks for

	if (info->target_desc != arches->gdbarch->target_desc)
	  continue;

So it never returns a gdbarch where any of the checks can fail.

Remove the duplicate check.  This also allows to move the lookup at the
start of the function.

gdb/ChangeLog:

	* s390-linux-tdep.c (s390_gdbarch_init): Remove douplicate checks when
	looking for cached gdbarch and move to start of function
---
 gdb/s390-linux-tdep.c | 26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)
  

Comments

Yao Qi Dec. 5, 2017, 4:16 p.m. UTC | #1
Philipp Rudo <prudo@linux.vnet.ibm.com> writes:

> -  /* Find a candidate among extant architectures.  */
> -  for (arches = gdbarch_list_lookup_by_info (arches, &info);
> -       arches != NULL;
> -       arches = gdbarch_list_lookup_by_info (arches->next, &info))
> -    {
> -      tdep = gdbarch_tdep (arches->gdbarch);
> -      if (!tdep)
> -	continue;
> -      if (tdep->abi != tdep_abi)
> -	continue;
> -      if (tdep->vector_abi != vector_abi)
> -	continue;

Is it possible that we have two instances of gdbarch, with the same
target description, but different vector_abi?  Two different executables
compiled with different vector abis, and GDB can debug them together
(multi-process debugging.  If we consider multi-target debugging in the
future, these two executable can from different targets).

> -      if ((tdep->gpr_full_regnum != -1) != have_upper)
> -	continue;
> -      if (tdep->have_gs != have_gs)
> -	continue;
> -      if (tdesc_data != NULL)
> -	tdesc_data_cleanup (tdesc_data);
> -      return arches->gdbarch;
> -    }
  
Philipp Rudo Dec. 6, 2017, 9:56 a.m. UTC | #2
Hi Yao,


On Tue, 05 Dec 2017 16:16:07 +0000
Yao Qi <qiyaoltc@gmail.com> wrote:

> Philipp Rudo <prudo@linux.vnet.ibm.com> writes:
> 
> > -  /* Find a candidate among extant architectures.  */
> > -  for (arches = gdbarch_list_lookup_by_info (arches, &info);
> > -       arches != NULL;
> > -       arches = gdbarch_list_lookup_by_info (arches->next, &info))
> > -    {
> > -      tdep = gdbarch_tdep (arches->gdbarch);
> > -      if (!tdep)
> > -	continue;
> > -      if (tdep->abi != tdep_abi)
> > -	continue;
> > -      if (tdep->vector_abi != vector_abi)
> > -	continue;  
> 
> Is it possible that we have two instances of gdbarch, with the same
> target description, but different vector_abi?  Two different executables
> compiled with different vector abis, and GDB can debug them together
> (multi-process debugging.  If we consider multi-target debugging in the
> future, these two executable can from different targets).

For s390 there only is one vector abi (or non at all) at the time.  If you were
debugging two different executables at the same time you would have two
inferiors each with its own gdbarch (same would be for multi-target debugging).
So I don't think those are the reasons.

For me it more looks like a mix of copy&paste code combined with an improper
clean up when the gdbarch_info->tdesc field was introduced.  This pattern was
introduced in 2000 (7a78ae4e6b0) for ppc/rs6k (in rs6000-tdep.c) and copy&pasted
to s390 in 2010 (7803799a0fb).  Between the two commits in 2006 (424163ea152)
the tdesc field (with the corresponding check) was added to gdbarch_info
without cleaning up the uses of gdbarch_list_lookup_by_info.  Unfortunately
none of the commits have a commit message and the ChangeLog isn't very
helpful...

Thanks
Philipp

> > -      if ((tdep->gpr_full_regnum != -1) != have_upper)
> > -	continue;
> > -      if (tdep->have_gs != have_gs)
> > -	continue;
> > -      if (tdesc_data != NULL)
> > -	tdesc_data_cleanup (tdesc_data);
> > -      return arches->gdbarch;
> > -    }  
>
  
Philipp Rudo Dec. 7, 2017, 9:17 a.m. UTC | #3
Hi Yao,

I quickly talked to Uli yesterday about this and you and Uli are right.  There
is a possibility that a program chooses not to use the vector registers for
their abi even when they are present.  I fixed the patch locally.

Thanks for catching this!
Philipp


On Wed, 6 Dec 2017 11:28:23 +0100 (CET)
"Ulrich Weigand" <uweigand@de.ibm.com> wrote:

> Philipp Rudo wrote:
> 
> > On Tue, 05 Dec 2017 16:16:07 +0000
> > Yao Qi <qiyaoltc@gmail.com> wrote:  
> > > Is it possible that we have two instances of gdbarch, with the same
> > > target description, but different vector_abi?  Two different executables
> > > compiled with different vector abis, and GDB can debug them together
> > > (multi-process debugging.  If we consider multi-target debugging in the
> > > future, these two executable can from different targets).  
> > 
> > For s390 there only is one vector abi (or non at all) at the time.  If you were
> > debugging two different executables at the same time you would have two
> > inferiors each with its own gdbarch (same would be for multi-target debugging).
> > So I don't think those are the reasons.  
> 
> Actually, I think Yao is right here.  As you say, we can have two executables,
> one using the vector ABI and one not.  These will require two different gdbarch
> structures.  But with the patch you propose, when trying to allocate the second
> of those two, GDB would see the first one that was already created earlier,
> and incorrectly assume that it can simply be reused.
> 
> Basically, the problem is that there *can* be different gdbarchs that share
> the *same* tdesc, but differ in vector ABI.  Therefore *only* checking for
> tdesc does not suffice to correctly identify cached gdbarch structures.
> 
> I agree that it is redundant to again check differences (e.g. in register set)
> that would already have led to a different tdesc; but the vector ABI at least
> is not one of those.
> 
> Bye,
> Ulrich
>
  
Yao Qi Dec. 7, 2017, 9:59 a.m. UTC | #4
On Thu, Dec 7, 2017 at 9:17 AM, Philipp Rudo <prudo@linux.vnet.ibm.com> wrote:
> Hi Yao,
>
> I quickly talked to Uli yesterday about this and you and Uli are right.  There
> is a possibility that a program chooses not to use the vector registers for
> their abi even when they are present.  I fixed the patch locally.
>
> Thanks for catching this!

Great, happy to help :)
  

Patch

diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index a0d4cdd740..e3e036a70d 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -7829,6 +7829,11 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   static const char *const stap_register_indirection_suffixes[] = { ")",
 								    NULL };
 
+  /* Find a candidate among extant architectures.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return arches->gdbarch;
+
   /* Default ABI and register size.  */
   switch (info.bfd_arch_info->mach)
     {
@@ -8040,27 +8045,6 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     vector_abi = S390_VECTOR_ABI_128;
 #endif
 
-  /* Find a candidate among extant architectures.  */
-  for (arches = gdbarch_list_lookup_by_info (arches, &info);
-       arches != NULL;
-       arches = gdbarch_list_lookup_by_info (arches->next, &info))
-    {
-      tdep = gdbarch_tdep (arches->gdbarch);
-      if (!tdep)
-	continue;
-      if (tdep->abi != tdep_abi)
-	continue;
-      if (tdep->vector_abi != vector_abi)
-	continue;
-      if ((tdep->gpr_full_regnum != -1) != have_upper)
-	continue;
-      if (tdep->have_gs != have_gs)
-	continue;
-      if (tdesc_data != NULL)
-	tdesc_data_cleanup (tdesc_data);
-      return arches->gdbarch;
-    }
-
   /* Otherwise create a new gdbarch for the specified machine type.  */
   tdep = XCNEW (struct gdbarch_tdep);
   tdep->abi = tdep_abi;