From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23100 invoked by alias); 24 Aug 2010 16:57:33 -0000 Received: (qmail 23090 invoked by uid 22791); 24 Aug 2010 16:57:30 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 24 Aug 2010 16:57:19 +0000 Received: (qmail 30270 invoked from network); 24 Aug 2010 16:57:17 -0000 Received: from unknown (HELO orlando.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 24 Aug 2010 16:57:17 -0000 From: Pedro Alves To: gdb-patches@sourceware.org, Doug Evans Subject: Teach inherit_abstract_dies about inter-cu references Date: Tue, 24 Aug 2010 16:57:00 -0000 User-Agent: KMail/1.13.2 (Linux/2.6.33-29-realtime; KDE/4.4.2; x86_64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Message-Id: <201008241757.12786.pedro@codesourcery.com> X-IsSubscribed: yes 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: 2010-08/txt/msg00412.txt.bz2 Doug, here's the patch we were talking about on IRC. Below's also=20 (a slightly tweaked) original description of the problem. A while ago, I stumbled on this crash using a customer's binary compiled with RealView: Program received signal SIGSEGV, Segmentation fault. 0x00000000005793c2 in add_symbol_to_list (symbol=3D0x182ed130, listhead=3D= 0x0) at ../../src/gdb/buildsym.c:139 139 if (*listhead =3D=3D NULL || (*listhead)->nsyms =3D=3D PENDINGSI= ZE) (top-gdb) The crash was here: #1 0x000000000059c014 in new_symbol (die=3D0x182eeab0, type=3D0x182ecf10,= cu=3D0x9f91cf0) at ../../src/gdb/dwarf2read.c:8406 #2 0x0000000000590815 in process_die (die=3D0x182eeab0, cu=3D0x9f91cf0) a= t ../../src/gdb/dwarf2read.c:3087 #3 0x0000000000591903 in inherit_abstract_dies (die=3D0x180b09a0, cu=3D0x= 9f91cf0) at ../../src/gdb/dwarf2read.c:3586 #4 0x0000000000591bf2 in read_func_scope (die=3D0x180b09a0, cu=3D0x91bcaf= 0) at ../../src/gdb/dwarf2read.c:3667 #5 0x000000000059079f in process_die (die=3D0x180b09a0, cu=3D0x91bcaf0) a= t ../../src/gdb/dwarf2read.c:3053 That is, `cu->list_in_scope' is NULL when new_symbol is called. The problem is that inherit_abstract_dies isn't coping with inter-cu references, and so is assuming the origin die is always in the same compilation unit as the incoming die. In the issue's binary, when the crash occurs, this in `inherit_abstract_dies': origin_die =3D follow_die_ref (die, attr, &cu); ^^ (that's a inout parameter) returns a different cu from what was passed in. = This other CU doesn't have the list_in_scope member set yet. Also, further below, we'll pass the origin_die's cu to other functions, paired with a die from another cu. E.g.: struct die_info *child_origin_die =3D child_die; attr =3D dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu); This should have been the incoming DIE's cu, or child_origin_die's in following iterations. Here's the patch to fix these issues. It fixed the crash and had no regressions with ARM RealView, and I just retested it on x86_64-linux-gnu with no regression as well. --=20 Pedro Alves 2010-08-24 Pedro Alves gdb/ * dwarf2read.c (inherit_abstract_dies): Handle origin die's compilation unit being different from target die's. Index: gdb/dwarf2read.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gdb/dwarf2read.c (revis=E3o 278502) +++ gdb/dwarf2read.c (revis=E3o 278503) @@ -3977,12 +3977,24 @@ inherit_abstract_dies (struct die_info * struct die_info *origin_child_die; struct cleanup *cleanups; struct attribute *attr; + struct dwarf2_cu *origin_cu; + struct pending **origin_previous_list_in_scope; =20 attr =3D dwarf2_attr (die, DW_AT_abstract_origin, cu); if (!attr) return; =20 - origin_die =3D follow_die_ref (die, attr, &cu); + /* Note that following die references may follow to a die in a + different cu. */ + + origin_cu =3D cu; + origin_die =3D follow_die_ref (die, attr, &origin_cu); + + /* We're inheriting ORIGIN's children into the scope we'd put DIE's + symbols in. */ + origin_previous_list_in_scope =3D origin_cu->list_in_scope; + origin_cu->list_in_scope =3D cu->list_in_scope; + if (die->tag !=3D origin_die->tag && !(die->tag =3D=3D DW_TAG_inlined_subroutine && origin_die->tag =3D=3D DW_TAG_subprogram)) @@ -4010,12 +4022,15 @@ inherit_abstract_dies (struct die_info * but GCC versions at least through 4.4 generate this (GCC PR 40573). */ struct die_info *child_origin_die =3D child_die; + struct dwarf2_cu *child_origin_cu =3D cu; while (1) { - attr =3D dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu); + attr =3D dwarf2_attr (child_origin_die, DW_AT_abstract_origin, + child_origin_cu); if (attr =3D=3D NULL) break; - child_origin_die =3D follow_die_ref (child_origin_die, attr, &cu); + child_origin_die =3D follow_die_ref (child_origin_die, attr, + &child_origin_cu); } =20 /* According to DWARF3 3.3.8.2 #3 new entries without their abstract @@ -4057,10 +4072,11 @@ inherit_abstract_dies (struct die_info * if (offsetp >=3D offsets_end || *offsetp > origin_child_die->offset) { /* Found that ORIGIN_CHILD_DIE is really not referenced. */ - process_die (origin_child_die, cu); + process_die (origin_child_die, origin_cu); } origin_child_die =3D sibling_die (origin_child_die); } + origin_cu->list_in_scope =3D origin_previous_list_in_scope; =20 do_cleanups (cleanups); }