Date: Thu, 18 Sep 2014 20:46:59 +0200 From: Dimitry Andric <dim@FreeBSD.org> To: Will Andrews <will@freebsd.org> Cc: Justin Gibbs <gibbs@freebsd.org>, jkoshy@freebsd.org, freebsd-toolchain@freebsd.org, kaiw@freebsd.org Subject: Re: elftoolchain update? Message-ID: <D44FDBD9-F6AF-48B1-A467-9C51C685E750@FreeBSD.org> In-Reply-To: <CADBaqmgasfbP6r09yAsmrw-eVHqm3AWSuBdA5tHf5U5rj8j2HA@mail.gmail.com> References: <CADBaqmgasfbP6r09yAsmrw-eVHqm3AWSuBdA5tHf5U5rj8j2HA@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--Apple-Mail=_30E0948E-EB5E-4D45-B37A-695A9D42D0B0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On 18 Sep 2014, at 01:01, Will Andrews <will@freebsd.org> wrote: > I see there have been a lot of updates & fixes to elftoolchain since > the last import into FreeBSD/head nearly 8 months ago. Are there any > plans to update the import? >=20 > I'm asking because it appears that ctfconvert currently crashes > (specifically, due to a bug in dwarf_attrval_unsigned()), if you try > to use it on C++ object files. >=20 > This is easily demonstrated by applying this patch to FreeBSD/head and > building sbin/devd with WITH_CTF=3D1: > = http://people.freebsd.org/~will/add-ctfconvert-to-cpp-object-files.diff >=20 > Justin Gibbs (cc'd) posted about this issue in February, and it's > still a problem: > = http://lists.freebsd.org/pipermail/freebsd-toolchain/2014-February/001121.= html In that previous thread, I was not able to reproduce any problems with ctfconvert or ctfmerge, but I have tried it again just now, and I think it is a problem in libdwarf. The crash goes like this: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 28803080 (LWP 100196)] 0x280bb75d in dwarf_attrval_unsigned (die=3D0x28941f10, attr=3D73, = valp=3D0xbfbfdea0, err=3D0xbfbfe0a4) at = /usr/src/lib/libdwarf/../../contrib/elftoolchain/libdwarf/dwarf_attrval.c:= 186 186 switch (at->at_form) { (gdb) bt #0 0x280bb75d in dwarf_attrval_unsigned (die=3D0x28941f10, attr=3D73, = valp=3D0xbfbfdea0, err=3D0xbfbfe0a4) at = /usr/src/lib/libdwarf/../../contrib/elftoolchain/libdwarf/dwarf_attrval.c:= 186 #1 0x08052a45 in die_attr_ref (dw=3D0xbfbfe0a0, die=3D0x28941f10, = name=3D73) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:417 #2 0x08052844 in die_lookup_pass1 (dw=3D0xbfbfe0a0, die=3D0x28941f10, = name=3D73) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:476 #3 0x08052380 in die_variable_create (dw=3D0xbfbfe0a0, die=3D0x28941f10, = off=3D83907, tdp=3D0x0) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:1680 #4 0x08050940 in die_create_one (dw=3D0xbfbfe0a0, die=3D0x28941f10) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:1793 #5 0x0804fa94 in die_create (dw=3D0xbfbfe0a0, die=3D0x28941f10) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:1800 #6 0x0804f368 in dw_read (td=3D0x2881c040, elf=3D0x28830040, = filename=3D0xbfbfe83e "devd.o") at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:2003 #7 0x0804eb6e in file_read (td=3D0x2881c040, filename=3D0xbfbfe83e = "devd.o", ignore_non_c=3D0) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/ctfconvert.c:115 #8 0x0804e7ca in main (argc=3D5, argv=3D0xbfbfe694) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/ctfconvert.c:236 (gdb) print at $1 =3D (Dwarf_Attribute) 0x0 Looking at dwarf_attrval_unsigned(), you can see 'at' being NULL-checked in line 163, but if the _dwarf_attr_find() call on line 164 then also returns NULL, the switch on line 186 will segfault as above: 140 int 141 dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, = Dwarf_Unsigned *valp, Dwarf_Error *err) 142 { 143 Dwarf_Attribute at; ... 157 if ((at =3D _dwarf_attr_find(die, attr)) =3D=3D NULL && = attr !=3D DW_AT_type) { 158 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 159 return (DW_DLV_NO_ENTRY); 160 } 161 162 die1 =3D NULL; 163 if (at =3D=3D NULL && 164 (at =3D _dwarf_attr_find(die, = DW_AT_abstract_origin)) !=3D NULL) { ... 184 } 185 186 switch (at->at_form) { ... I'm not sure what kind of error code should be returned when the second _dwarf_attr_find() fails, though. Or if that is some sort of problem with a symbol? If I go to frame 3 (die_variable_create), the name seems to be the empty string, but not a NULL pointer: (gdb) frame 3 #3 0x08052380 in die_variable_create (dw=3D0xbfbfe0a0, die=3D0x28941f10, = off=3D83907, tdp=3D0x0) at = /usr/src/cddl/usr.bin/ctfconvert/../../../cddl/contrib/opensolaris/tools/c= tf/cvt/dwarf.c:1680 1680 ii->ii_dtype =3D die_lookup_pass1(dw, die, DW_AT_type); (gdb) print name $2 =3D 0x2892dc90 "" The name is looked up on line 1674, where nameless objects are supposed to be skipped: 1666 static void 1667 die_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, = tdesc_t *tdp __unused) 1668 { 1669 iidesc_t *ii; 1670 char *name; 1671 1672 debug(3, "die %llu: creating object definition\n", off); 1673 1674 if (die_isdecl(dw, die) || (name =3D die_name(dw, die)) = =3D=3D NULL) 1675 return; /* skip prototypes and nameless objects = */ 1676 1677 ii =3D xcalloc(sizeof (iidesc_t)); 1678 ii->ii_type =3D die_isglobal(dw, die) ? II_GVAR : = II_SVAR; 1679 ii->ii_name =3D name; 1680 ii->ii_dtype =3D die_lookup_pass1(dw, die, DW_AT_type); However, die_name() does not ever seem to return NULL (the code to return the empty string was added by Kai in r261246): 425 static char * 426 die_name(dwarf_t *dw, Dwarf_Die die) 427 { 428 char *str =3D NULL; 429 430 (void) die_string(dw, die, DW_AT_name, &str, 0); 431 if (str =3D=3D NULL) 432 str =3D xstrdup(""); 433 434 return (str); 435 } There are quite a lot of places in this file where the result of die_name() is explicitly checked against NULL, so maybe always returning an empty string was not such a good idea. It may have been done to avoid another segfault. The way forward is probably to: * fix the situation in dwarf_attrval_unsigned(), returning a sensible error value if both lookups fail. * make die_name() return a NULL pointer again, or explicitly check for the empty string in die_variable_create(). -Dimitry --Apple-Mail=_30E0948E-EB5E-4D45-B37A-695A9D42D0B0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.22 (Darwin) iEYEARECAAYFAlQbKKgACgkQsF6jCi4glqNK5gCfTxBhMscesG9ogoJfu99Ownts icAAn1NUB56P1rzA7OsvTL2nzUyWikDi =hp85 -----END PGP SIGNATURE----- --Apple-Mail=_30E0948E-EB5E-4D45-B37A-695A9D42D0B0--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?D44FDBD9-F6AF-48B1-A467-9C51C685E750>