From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15243 invoked by alias); 3 Apr 2008 21:30:21 -0000 Received: (qmail 15234 invoked by uid 22791); 3 Apr 2008 21:30:20 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 03 Apr 2008 21:29:52 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id C505E2A996C for ; Thu, 3 Apr 2008 17:29:50 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 5EcvrLwS4110 for ; Thu, 3 Apr 2008 17:29:50 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 34F4A2A997F for ; Thu, 3 Apr 2008 17:29:50 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id D653CE7ACD; Thu, 3 Apr 2008 14:29:47 -0700 (PDT) Date: Thu, 03 Apr 2008 21:59:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [RFA/stabs] fix failed assertion during replacement of undefined type Message-ID: <20080403212947.GA24753@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="UlVJffcvxoiEqYs2" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-04/txt/msg00081.txt.bz2 --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3298 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 * 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 * 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 --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="stabsread.diff" Content-length: 1948 Index: stabsread.c =================================================================== RCS file: /cvs/src/src/gdb/stabsread.c,v retrieving revision 1.105 diff -u -p -r1.105 stabsread.c --- stabsread.c 26 Mar 2008 14:53:28 -0000 1.105 +++ stabsread.c 3 Apr 2008 20:50:52 -0000 @@ -4287,6 +4287,25 @@ cleanup_undefined_types_1 (void) { struct type **type; + /* Iterate over every undefined type, and look for a symbol whose type + matches our undefined type. The symbol matches if: + 1. It is a typedef in the STRUCT domain; + 2. It has the same name, and same type code; + 3. The instance flags are identical. + + It is important to check the instance flags, because we have seen + examples where the debug info contained definitions such as: + + "foo_t:t30=B31=xefoo_t:" + + In this case, we have created an undefined type named "foo_t" whose + instance flags is null (when processing "xefoo_t"), and then created + another type with the same name, but with different instance flags + ('B' means volatile). I think that the definition above is wrong, + since the same type cannot be volatile and non-volatile at the same + time, but we need to be able to cope with it when it happens. The + approach taken here is to treat these two types as different. */ + for (type = undef_types; type < undef_types + undef_types_length; type++) { switch (TYPE_CODE (*type)) @@ -4322,7 +4341,10 @@ cleanup_undefined_types_1 (void) && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE (*type)) - && strcmp (DEPRECATED_SYMBOL_NAME (sym), typename) == 0) + && (TYPE_INSTANCE_FLAGS (*type) == + TYPE_INSTANCE_FLAGS (SYMBOL_TYPE (sym))) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), + typename) == 0) replace_type (*type, SYMBOL_TYPE (sym)); } } --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="atomic_enum.exp" Content-length: 1423 # Copyright 2008 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . if $tracelevel then { strace $tracelevel } load_lib "ada.exp" set testdir "atomic_enum" set testfile "${testdir}/foo" set srcfile ${srcdir}/${subdir}/${testfile}.adb set binfile ${objdir}/${subdir}/${testfile} file mkdir ${objdir}/${subdir}/${testdir} if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional_flags=-gnat05 ]] != "" } { return -1 } gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} set test "ptype pck.data_flag" gdb_test_multiple "$test" $test { -re "type = \\(one, two, three\\).*$gdb_prompt $" { pass $test } -re "type = \\(\\).*$gdb_prompt $" { # This is a known compiler problem with Stabs. xfail $test } } --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pck.ads" Content-length: 797 -- Copyright 2008 Free Software Foundation, Inc. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . package Pck is procedure Increment; function Is_First return Boolean; end Pck; --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pck.adb" Content-length: 1141 -- Copyright 2008 Free Software Foundation, Inc. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . package body Pck is type Data_T is (One, Two, Three); pragma Atomic (Data_T); Data_Flag : Data_T := One; procedure Increment is begin if Data_Flag = Data_T'Last then Data_Flag := Data_T'First; else Data_Flag := Data_T'Succ (Data_Flag); end if; end Increment; function Is_First return Boolean is begin return Data_Flag = Data_T'First; end Is_First; end Pck; --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="foo.adb" Content-length: 810 -- Copyright 2008 Free Software Foundation, Inc. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . with Pck; use Pck; procedure Foo is begin if Is_First then Increment; end if; end Foo; --UlVJffcvxoiEqYs2--