This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA/stabs] fix failed assertion during replacement of undefined type


Hello,

First off: I hate stabs (I feel better now). Unfortunately, we haven't
been able to transition certain platforms such as AIX to DWARF, so
we're stuck with it for a little while longer. I was able to reproduce
the same problem on x86-linux with -gstabs+, so the following analysis
will assume x86-linux.

I came across a case that causes the following internal error while
reading some debugging info.

    (gdb) ptype pck.data_flag
    gdbtypes.c:640: internal-error: replace_type: Assertion `TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type)' failed.
    A problem internal to GDB has been detected,
    further debugging may prove unreliable.
    Quit this debugging session? (y or n)

This type of this variable is define as an enumerated type with
an associated pragma Atomic:

   type Data_T is (One, Two, Three);
   pragma Atomic (Data_T);

The compiler ended up emitting the following debugging info for this
type, which is incomplete:

    .stabs  "pck__data_t:t(0,32)=B(0,33)=xepck__data_t:",128,0,3,0

Here is what happens chonologically:

  1. The reference to pck__data_t ("xepck__data_t") cannot be resolved
     because this type hasn't been defined yet - in fact, this entry
     is a broken attempt at defining it.  So we create a stub type
     for it with name "pck__data_t", and null instance flags.

  2. Now that our referenced type has been created, we're trying to
     create the volatile version ('B') of our new type, and so we
     create a new type with the same name, but different instance
     flags.

  3. After having processed all debugging info for this unit, we try
     to resolve all the types that are still undefined, and we do this
     more or less by matching by name (we actually also check type code
     as well as class & domain).

     For our type above, we end up finding the symbol whose type is
     volatile, and try to replace the undefined version by the one
     we just found.  This is when replace_type reports the failed
     assertion.

The debugging info is screwy, and I've asked our GCC team to look into
this. But in the meantime, it's pretty simple to handle the situation
more gracefully. I had several ideas, one of them being to smash the
instance flags of the undefined type.  But this doesn't bring any
benefit, since we would be replacing our undefined type by an incomplete
type. So I decided to take an even simpler approach and treat the types
as different, and not do the replacement unless the instance flags are
consistent. I've added a comment explaining how we do our matching and
why checking the instance flags is necessary.

2008-04-03  Joel Brobecker  <brobecker@adacore.com>

        * stabsread.c (cleanup_undefined_types_1): Add instance flags check
        in the search for the matching symbol.

Tested on x86-linux with -gstabs+.

I also wrote a new testcase

2008-04-03  Joel Brobecker  <brobecker@adacore.com>

	* gdb.ada/atomic_enum: New test program.
        * gdb.ada/atomic_enum.exp: New testcase.

Before the patch is applied, I get with -gstabs+:

    FAIL: gdb.ada/atomic_enum.exp: ptype pck.data_flag (GDB internal error)

After the patch is applied, I get an XFAIL. And if the example program
is built with DWARF, then I get a PASS before and after.

OK to apply?

Thanks,
-- 
Joel

Attachment: stabsread.diff
Description: Text document

Attachment: atomic_enum.exp
Description: Text document

Attachment: pck.ads
Description: Text document

Attachment: pck.adb
Description: Text document

Attachment: foo.adb
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]