gdb 8.x - g++ 7.x compatibility
Hello, I'm trying to switch from g++ 5.4 to g++ 7.2. GDB 8.0.1 however does not understand RTTI generated by g++7.2, so my Python scripts for GDB are not working. Here is a code example: struct base { virtual ~base(){} }; template< int IVAL, unsigned UVAL, unsigned long long ULLVAL> struct derived : base { int x = IVAL + + UVAL + ULLVAL; }; int main() { base * o = new derived<1,2,3>{}; return 0; } When compiled with g++5.4 I can read value of x in debugger. When compiled with g++7.2 gdb reports: warning: RTTI symbol not found for class 'derived<1, 2u, 3ull>' Problem here is that type name saved in debug information is *derived<1, 2, 3>*, not *derived<1, 2u, 3ull>* Do you plan to fix this anytime soon? Thanks, Roman
Re: gdb 8.x - g++ 7.x compatibility
Yes, problem is still there in g++7.3 / gdb 8.1. I wonder why they decided to emit different strings to RTTI and debug info? What is the technical reason behind this? -Roman 2018-02-02 20:54 GMT-08:00 Simon Marchi : > On 2018-02-02 22:17, Roman Popov wrote: > >> Hello, >> I'm trying to switch from g++ 5.4 to g++ 7.2. >> GDB 8.0.1 however does not understand RTTI generated by g++7.2, so my >> Python scripts for GDB are not working. >> >> Here is a code example: >> >> struct base { virtual ~base(){} }; >> >> template< int IVAL, unsigned UVAL, unsigned long long ULLVAL> >> struct derived : base { >> int x = IVAL + + UVAL + ULLVAL; >> }; >> >> int main() >> { >> base * o = new derived<1,2,3>{}; >> return 0; >> } >> >> When compiled with g++5.4 I can read value of x in debugger. >> When compiled with g++7.2 gdb reports: >> warning: RTTI symbol not found for class 'derived<1, 2u, 3ull>' >> >> Problem here is that type name saved in debug information is >> *derived<1, 2, 3>*, not *derived<1, 2u, 3ull>* >> >> Do you plan to fix this anytime soon? >> >> Thanks, >> Roman >> > > Hi Roman, > > Your problem is probably linked to these issues, if you want to follow > them: > > gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81932 > gdb: https://sourceware.org/bugzilla/show_bug.cgi?id=22013 > > As Carl said, it's a good idea to try with the latest version of both > tools, but I think the issue will still be present. > > GCC changed how it outputs unsigned template parameters in the debug info > (from 2u to just 2), and it doesn't look like it's going to change it > back. So I suppose we'll have to find a way to make GDB deal with it. > > Simon >
Re: gdb 8.x - g++ 7.x compatibility
2018-02-02 20:54 GMT-08:00 Simon Marchi : > > GCC changed how it outputs unsigned template parameters in the debug info > (from 2u to just 2), and it doesn't look like it's going to change it > back. So I suppose we'll have to find a way to make GDB deal with it. > Simon > I'm not so sure about it. In my opinion it is a gcc bug. 2u and 2 are literals of different types. But I'm not a C++ expert. It looks like g++ and clang treat C++ language differently in this case. I've asked on stackoverflow: https://stackoverflow.com/questions/48594693/auto-template-parameters-g-7-3-vs-clang-6-0-which-compiler-is-correct If Clang is correct here, than foo<1u> and foo<1> are two different types. And so gcc should emit correct postfixes to debuginfo. -Roman
Re: gdb 8.x - g++ 7.x compatibility
I've just checked g++8.0.1 from trunk, and the problem is still there. And same with Clang compiler. This is indeed is a serious issue for me, since my Python scripts for gdb expect reliable dynamic type identification. However gdb is completely powerless here. So I'm forced to stay on older compiler. Consider this case (Results with g++ 8.0.1) #include struct base { virtual void print() = 0; }; template< auto IVAL> struct foo : base { decltype(IVAL) x = -IVAL; void print() override { std::cout << x << std::endl; }; }; int main() { base * fu = new foo<10u>(); base * fi = new foo<10>(); fu->print(); fi->print(); return 0; // set breakpoint here }: Now check dynamic types in GDB: (gdb) p *fu warning: RTTI symbol not found for class 'foo<10u>' $1 = warning: RTTI symbol not found for class 'foo<10u>' warning: RTTI symbol not found for class 'foo<10u>' {_vptr.base = 0x400bd0 +16>} (gdb) p *fi (gdb) p *fi $2 = (foo<10>) { = {_vptr.base = 0x400bb8 +16>}, *x = 4294967286*} Here GDB picks wrong type! In RTTI type names are different. And this is correct. But in debuginfo both types have same name: foo<10> { unsigned x; } foo<10> { int x; } So GDB picks the first one, which is wrong. -Roman 2018-02-03 6:20 GMT-08:00 Paul Smith : > On Fri, 2018-02-02 at 23:54 -0500, Simon Marchi wrote: > > Your problem is probably linked to these issues, if you want to follow > > them: > > > > gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81932 > > gdb: https://sourceware.org/bugzilla/show_bug.cgi?id=22013 > > > > As Carl said, it's a good idea to try with the latest version of both > > tools, but I think the issue will still be present. > > > > GCC changed how it outputs unsigned template parameters in the debug > > info (from 2u to just 2), and it doesn't look like it's going to change > > it back. So I suppose we'll have to find a way to make GDB deal with > > it. > > I also tried a couple of times [1][2][3] to get a discussion started on > the mailing lists for how to resolve this but didn't get any replies, > and I got busy with other things. > > We really need to find someone who is knowlegeable on type lookup in > GDB. That person needs to engage with the experts on the GCC side and > hash out the right answer to this problem. In my experience, Jonathan > Wakely on the GCC side is extremely responsive, I'm just too much of a > tyro to be able to discuss it with him at the level needed to find a > solution. > > I think it's an extremely serious issue, if GDB can't resolve some very > common (IME) types, but so far it hasn't risen to the level of getting > attention from those who have sufficient expertise to solve it. > > > [1] https://gcc.gnu.org/ml/gcc-help/2017-08/msg00120.html > [2] https://sourceware.org/ml/gdb/2017-08/msg00069.html > [3] https://sourceware.org/ml/gdb/2017-09/msg00042.html >
Re: gdb 8.x - g++ 7.x compatibility
Interestingly RTTI name also gives no guarantees: http://en.cppreference.com/w/cpp/types/type_info/name << Returns an implementation defined null-terminated character string containing the name of the type. No guarantees are given; in particular, the returned string can be identical for several types and change between invocations of the same program. >> It probably makes sense to look how g++ implements std::type_info::operator== . Probably there are some hints that GDB algorithm can utilize. Operator std::type_info::operator== must return true for equivalent types. 2018-02-05 8:59 GMT-08:00 Simon Marchi : > On 2018-02-05 11:45, Martin Sebor wrote: > >> Yes, with auto, the type of the constant does determine the type >> of the specialization of the template in the source code. >> >> In non-type template arguments, and more to the point I was making, >> in diagnostics, the suffix shouldn't or doesn't need to be what >> distinguishes the type of the template, even with auto. The part >> "with auto IVAL = 10" in the message >> >> 'void foo::print() [with auto IVAL = 10]': >> >> would be far clearer if auto were replaced by the deduced type, >> say along these lines: >> >> 'void foo::print() [with int IVAL = 10]': >> >> rather than relying on the suffix alone to distinguish between >> different specializations of the template. That seems far too >> subtle to me. But I think the diagnostic format is (or should >> be) independent of the debug info. >> > > That makes sense. > > With respect to the suffix, I keep coming back to the reality >> that even if GCC were to change to emit a format that GDB can >> interpret easily and efficiently, there still are other >> compilers that emit a different format. So the conclusion >> that a general solution that handles more than just one format >> (at least for non-type template arguments without auto) seems >> unescapable. >> > > If there are other compilers we wanted to support for which we can't trust > the template format, we could always ignore the template part of DW_AT_name > specifically for them. But since g++ and gdb are part of the same project > and are expected to work well and efficiently together, I would have hoped > that we could agree on a format so that gdb would not have to do the extra > work when parsing a g++-generated file (consequently the same format that > libiberty's demangler produces). > > Given the problem I illustrated in my previous mail, I don't have a > general solution to the problem to propose. > > Simon >
Re: gdb 8.x - g++ 7.x compatibility
Do you mean that g++ guarantees uniqueness of mangled names for types? And uses name compare for operator== ? 2018-02-05 12:08 GMT-08:00 Jonathan Wakely : > On 5 February 2018 at 17:44, Roman Popov wrote: > > Interestingly RTTI name also gives no guarantees: > > http://en.cppreference.com/w/cpp/types/type_info/name > > > > << Returns an implementation defined null-terminated character string > > containing the name of the type. No guarantees are given; in particular, > > the returned string can be identical for several types and change between > > invocations of the same program. >> > > > > It probably makes sense to look how g++ implements > > std::type_info::operator== . Probably there are some hints that GDB > > algorithm can utilize. > > Operator std::type_info::operator== must return true for equivalent > types. > > It's the mangled name. >
Re: gdb 8.x - g++ 7.x compatibility
Well, if ABI has specification for type naming, why not to put this name to debug_info so debugger can use it? In this case argument that "each producer has its own naming conventions" no longer works. Any producer for given ABI must use ABI-specified names. 2018-02-05 12:12 GMT-08:00 Jonathan Wakely : > On 5 February 2018 at 20:10, Roman Popov wrote: > > Do you mean that g++ guarantees uniqueness of mangled names for types? > And > > Of course. The mangled name is determined by the ABI and must be > stable, predictable and unique, so that linking works. > > > uses name compare for operator== ? > > Yes. >
Re: gdb 8.x - g++ 7.x compatibility
Is there any progress on this problem? I'm not familiar with G++ , but I have little experience with LLVM. I can try make LLVM emitting mangled names to DW_AT_name, instead of demangled ones. This way GDB can match DW_AT_name against RTTI. And for display it can call abi::__cxa_demangle(name, NULL, NULL, &status), from #include . Will it work? Thanks, Roman 2018-02-08 7:05 GMT-08:00 Richard Biener : > On Mon, Feb 5, 2018 at 6:06 AM, Simon Marchi > wrote: > > Hi Martin, > > > > Thanks for the reply. > > > > On 2018-02-04 02:17 PM, Martin Sebor wrote: > >> Printing the suffix is unhelpful because it leads to unnecessary > >> differences in diagnostics (even in non-template contexts). For > >> templates with non-type template parameters there is no difference > >> between, say A<1>, A<1U>, A<(unsigned) 1>, or even A when > >> Green is an enumerator that evaluates to 1, so including the suffix > >> serves no useful purpose. > > > > This is the part I don't understand. In Roman's example, spelling > > foo<10> and foo<10u> resulted in two different instantiations of the > > template, with different code. So that means it can make a difference, > > can't it? > > > >> In the GCC test suite, it would tend to > >> cause failures due to differences between the underlying type of > >> common typedefs like size_t and ptrdiff_t. Avoiding these > >> unnecessary differences was the main motivation for the change. > >> Not necessarily just in the GCC test suite but in all setups that > >> process GCC messages. > > > > Ok, I understand. > > > >> I didn't consider the use of auto as a template parameter but > >> I don't think it changes anything. There, just like in other > >> contexts, what's important is the deduced types and the values > >> of constants, not the minute details of how they are spelled. > > > > Well, it seems like using decltype on a template constant value is > > a way to make the type of constants important, in addition to their > > value. I know the standard seems to say otherwise (what Manfred > > quoted), but the reality seems different. I'm not a language expert > > so I can't tell if this is a deficiency in the language or not. > > > >> That said, it wasn't my intention to make things difficult for > >> the debugger. > > > > I hope so :). > > > >> But changing GCC back to include the suffix, > >> even just in the debug info, isn't a solution. There are other > >> compilers besides GCC that don't emit the suffixes, and there > >> even are some that prepend a cast to the number, so if GDB is > >> to be usable with all these kinds of producers it needs to be > >> able to handle all of these forms. > > > > As I said earlier, there are probably ways to make GDB cope with it. > > The only solution I saw (I'd like to hear about other ones) was to make > > GDB ignore the template part in DW_AT_name and re-build it from the > > DW_TAG_template_* DIEs in the format it expects. It can already do > > that somewhat, because, as you said, some compilers don't emit > > the template part in DW_AT_name. > > > > Doing so would cause major slowdowns in symbol reading, I've tried it > > for the sake of experimentation/discussion. I have a patch available > > on the "users/simark/template-suffix" branch in the binutils-gdb > > repo [1]. It works for Roman's example, but running the GDB testsuite > > shows that, of course, the devil is in the details. > > > > Consider something like this: > > > > template > > struct foo { virtual ~foo() {} }; > > > > int n; > > > > int main () > > { > > foo<&n> f; > > } > > > > > > The demangled name that GDB will be looking up is "foo<&n>". The > > debug info about the template parameter only contains the resulting > > address of n (the value of &n): > > > > <2>: Abbrev Number: 11 (DW_TAG_template_value_param) > >DW_AT_name: P > >DW_AT_type: <0x1ac> > >DW_AT_location: 10 byte block: 3 34 10 60 0 0 0 0 0 9f > (DW_OP_addr: 601034; DW_OP_stack_value) > > > > I don't see how GDB could reconstruct the "&n" in the template, so > > that's where my idea falls short. > > For other reasons I've always wanted sth like > > DW_OP_addr; DW_OP_name: n; DW_OP_stack_value > > thus put symbolical expressions in locations and have the consumer look > them up > (in context obviously). That way gdb can also choose to print foo > instead of > foo<1> or foo<>. > > Of course that needs DWARF extensions. > > Richard. > > > Simon > > > > [1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git; > a=shortlog;h=refs/heads/users/simark/template-suffix >
Re: gdb 8.x - g++ 7.x compatibility
Ok, sounds reasonable. In case of debugger we are indeed "linking" RTTI name with name in debuginfo. I've checked LLVM docs, they generate Debuginfo from LLVM "Metadata", and metadata for types already contains mangled names in "identifier" field: https://llvm.org/docs/LangRef.html#dicompositetype . So it should not be hard to propagate it to object file. I will ask on LLVM maillist if they can emit it. 2018-03-01 13:03 GMT-08:00 Jason Merrill : > On Thu, Mar 1, 2018 at 3:26 PM, Andrew Pinski wrote: > > On Thu, Mar 1, 2018 at 12:18 PM, Roman Popov wrote: > >> Is there any progress on this problem? > >> > >> I'm not familiar with G++ , but I have little experience with LLVM. I > can > >> try make LLVM emitting mangled names to DW_AT_name, instead of demangled > >> ones. > >> This way GDB can match DW_AT_name against RTTI. And for display it can > >> call abi::__cxa_demangle(name, NULL, NULL, &status), from #include > >> . > >> > >> Will it work? > > > > > > Reading http://wiki.dwarfstd.org/index.php?title=Best_Practices: > > the DW_AT_name attribute should contain the name of the corresponding > > program object as it appears in the source code, without any > > qualifiers such as namespaces, containing classes, or modules (see > > Section 2.15). A consumer can easily reconstruct the fully-qualified > > name from the DIE hierarchy. In general, the value of DW_AT_name > > should be such that a fully-qualified name constructed from the > > DW_AT_name attributes of the object and its containing objects will > > uniquely represent that object in a form natural to the source > > language. > > > > > > So having the mangled symbol in DW_AT_name seems backwards and not the > > point of it. > > If we add the mangled name, which seems reasonable, it should be in > DW_AT_linkage_name. > > Jason >
Re: gdb 8.x - g++ 7.x compatibility
I've experimented with adding DW_AT_linkage_name for composite types in LLVM. Here is impact on binary sizes (compiled with debuginfo): Original size with DW_AT_linkage_name for composites % increase clang-7.01926574256 1952846192 1.4% clang-tidy 1220980360 1238498112 1.4% llvm-mt 74047287525328 1.6% cout<<"hello";21552 22080 2.4% -Roman 2018-03-02 15:06 GMT-08:00 Roman Popov : > Ok, sounds reasonable. In case of debugger we are indeed "linking" RTTI > name with name in debuginfo. > > I've checked LLVM docs, they generate Debuginfo from LLVM "Metadata", and > metadata for types already contains mangled names in "identifier" field: > https://llvm.org/docs/LangRef.html#dicompositetype . So it should not be > hard to propagate it to object file. > > I will ask on LLVM maillist if they can emit it. > > > 2018-03-01 13:03 GMT-08:00 Jason Merrill : > >> On Thu, Mar 1, 2018 at 3:26 PM, Andrew Pinski wrote: >> > On Thu, Mar 1, 2018 at 12:18 PM, Roman Popov wrote: >> >> Is there any progress on this problem? >> >> >> >> I'm not familiar with G++ , but I have little experience with LLVM. I >> can >> >> try make LLVM emitting mangled names to DW_AT_name, instead of >> demangled >> >> ones. >> >> This way GDB can match DW_AT_name against RTTI. And for display it can >> >> call abi::__cxa_demangle(name, NULL, NULL, &status), from #include >> >> . >> >> >> >> Will it work? >> > >> > >> > Reading http://wiki.dwarfstd.org/index.php?title=Best_Practices: >> > the DW_AT_name attribute should contain the name of the corresponding >> > program object as it appears in the source code, without any >> > qualifiers such as namespaces, containing classes, or modules (see >> > Section 2.15). A consumer can easily reconstruct the fully-qualified >> > name from the DIE hierarchy. In general, the value of DW_AT_name >> > should be such that a fully-qualified name constructed from the >> > DW_AT_name attributes of the object and its containing objects will >> > uniquely represent that object in a form natural to the source >> > language. >> > >> > >> > So having the mangled symbol in DW_AT_name seems backwards and not the >> > point of it. >> >> If we add the mangled name, which seems reasonable, it should be in >> DW_AT_linkage_name. >> >> Jason >> > >