Bug 49130 - discrepancies between DW_AT_name and demangler
Summary: discrepancies between DW_AT_name and demangler
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 49312
Blocks:
  Show dependency treegraph
 
Reported: 2011-05-23 20:56 UTC by Tom Tromey
Modified: 2024-01-21 15:55 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2011-05-23 20:56:31 UTC
From the tail of this email: http://sourceware.org/ml/gdb-patches/2011-05/msg00524.html

There are a number of places where DW_AT_name disagrees with the demangler:

Computed physname <WTF::FixedArray<double, 8u>::data()> does not match demangled <WTF::FixedArray<double, 8ul>::data()> (from linkage <_ZN3WTF10FixedArrayIdLm8EE4dataEv>)
 - FYI its DW_TAG_class_type DW_AT_name is: FixedArray<double, 8u>
Computed physname <WTF::PtrHash<void const*>::hash(void*)> does not match demangled <WTF::PtrHash<void const*>::hash(void const*)> (from linkage <_ZN3WTF7PtrHashIPKvE4hashES2_>)
 - const issue
Computed physname <WebCore::RangeBoundaryPoint::offset()> does not match demangled <WebCore::RangeBoundaryPoint::offset() const> (from linkage <_ZNK7WebCore18RangeBoundaryPoint6offsetEv>)
 - maybe different const issue


(I didn't verify the const issues in the DWARF, it may be a gdb bug)

I think it would be best if DW_AT_name matched the demangler in all cases.
(I think it is arguable whether DW_AT_name should include the template
parameters; but we should at least discuss on the gdb list before considering
this, and anyway this would require a complete solution to PR 41736)

See also PR 33861
Comment 1 Richard Biener 2011-05-24 10:14:57 UTC
I think it would be nicer if there were a DW_AT_mangled_name we could use
instead because it's shorter.  This also would avoid inconsistencies.
Comment 2 Jan Kratochvil 2011-05-27 13:55:45 UTC
Those Comment 0 samples are instead from:
/usr/lib/debug/usr/lib64/libwebkitgtk-1.0.so.0.5.2.debug
webkitgtk-debuginfo-1.3.10-1.fc14.x86_64
Comment 3 Tom Tromey 2011-05-27 16:59:57 UTC
Here is another case:

template<class K, unsigned long l>
class S2
{
};

template<typename T> void f(S2<T, sizeof(T*)>) { }

int main()
{
  S2<double, sizeof(double*)> s;
  f<double> (s);
}


This generates:

 <1><29>: Abbrev Number: 2 (DW_TAG_class_type)
    <2a>   DW_AT_name        : (indirect string, offset: 0x88): S2<double, 4ul>	
    <2e>   DW_AT_byte_size   : 1	
    <2f>   DW_AT_decl_file   : 1	
    <30>   DW_AT_decl_line   : 2	
    <31>   DW_AT_sibling     : <0x45>	
 <2><35>: Abbrev Number: 3 (DW_TAG_template_type_param)
    <36>   DW_AT_name        : K	
    <38>   DW_AT_type        : <0xad>	
 <2><3c>: Abbrev Number: 4 (DW_TAG_template_value_param)
    <3d>   DW_AT_name        : l	
    <3f>   DW_AT_type        : <0xb4>	
    <43>   DW_AT_const_value : 4	


Note that both DW_AT_name and DW_TAG_template_value_param are
incorrect.  The demangler gets it right:

   void f<double>(S2<double, sizeof (double*)>)
Comment 4 Tom Tromey 2011-05-27 17:03:09 UTC
I forgot to mention -- you can construct many more such cases
using the expressions feature of the mangling:

http://www.codesourcery.com/public/cxx-abi/abi.html#expressions

This also affects PR 41736
Comment 5 dodji@seketeli.org 2011-05-27 17:27:43 UTC
In the example below, I could reproduce a case of difference between the
mangled name and the content of DW_AT_name.

Basically the content of the DW_AT_name property of the instanciation of
S is S<2048u>, and the mangled name of the member function f is
_ZN1N1SILm2048EE1fEm --> N::S<2048ul>::f(unsigned long).  Notice how the
former S<2048u> and the latter S<2048ul> are different.

typedef long unsigned int size_t;

static const size_t KB = 1024;
static const size_t atomSize = sizeof(double);
static const size_t blockSize = 16 * KB;

namespace N {
template<size_t size>
struct S
{
    void f(size_t);
};

template<size_t size>
inline void
S<size>::f(size_t)
{
    size_t i = size;
}

}

int
main()
{
    N::S<blockSize / atomSize> s1;
    s1.f(10);
}
Comment 6 Jan Kratochvil 2011-05-30 08:44:43 UTC
Another issue is with DMGL_VERBOSE.  nm -C does not use DMGL_VERBOSE:
libstdc++.so.6.0.16.debug
00000000000a4e50 t bool __gnu_cxx::operator==<char*, std::string>(__gnu_cxx::__normal_iterator<char*, std::string> const&, __gnu_cxx::__normal_iterator<char*, std::string> const&)

But the DIE uses "DMGL_VERBOSE":
 <2><1836e2>: Abbrev Number: 29 (DW_TAG_subprogram)
    <1836e4>   DW_AT_name        : (indirect string, offset: 0x2e3f0): operator==<char*, std::basic_string<char> >
 <1><188ab4>: Abbrev Number: 103 (DW_TAG_subprogram)
    <188ab5>   DW_AT_specification: <0x1836e2>
 <1><193100>: Abbrev Number: 129 (DW_TAG_subprogram)
    <193102>   DW_AT_abstract_origin: <0x188ab4>
    <193106>   DW_AT_low_pc      : 0xa4e50
Comment 7 dodji@seketeli.org 2011-05-31 11:16:16 UTC
"jan.kratochvil at redhat dot com" <gcc-bugzilla@gcc.gnu.org> a écrit:

> --- Comment #6 from Jan Kratochvil <jan.kratochvil at redhat dot com> 2011-05-30 08:44:43 UTC ---
> Another issue is with DMGL_VERBOSE.  nm -C does not use DMGL_VERBOSE:
> libstdc++.so.6.0.16.debug
> 00000000000a4e50 t bool __gnu_cxx::operator==<char*,
> std::string>(__gnu_cxx::__normal_iterator<char*, std::string> const&,
> __gnu_cxx::__normal_iterator<char*, std::string> const&)
>
> But the DIE uses "DMGL_VERBOSE":
>  <2><1836e2>: Abbrev Number: 29 (DW_TAG_subprogram)
>     <1836e4>   DW_AT_name        : (indirect string, offset: 0x2e3f0):
> operator==<char*, std::basic_string<char> >
>  <1><188ab4>: Abbrev Number: 103 (DW_TAG_subprogram)
>     <188ab5>   DW_AT_specification: <0x1836e2>
>  <1><193100>: Abbrev Number: 129 (DW_TAG_subprogram)
>     <193102>   DW_AT_abstract_origin: <0x188ab4>
>     <193106>   DW_AT_low_pc      : 0xa4e50

I understand that DW_AT_name and DW_AT_MIPS_linkage_name being
/gratuitously/ different can be an issue.  But here, I understand what
you are highlighting as a different matter.

nm -C is compressing[1] the output to avoid cluttering it too much.  But
DW_AT_name really represents the name of the operator as written in the
source code[2], with its template parameters replaced with their
corresponding arguments.

How would that be an issue?


[1]: http://www.codesourcery.com/public/cxx-abi/abi.html#mangling, look
for 'compression' (chapter 5.1.8 there).

[2]: DWARF4 spec, 1.21 [Identitier Names] says:
     "DW_AT_name attribute, whose value is a string representing the
     name as it appears in the source program"
Comment 8 Dodji Seketeli 2011-06-07 11:12:55 UTC
Author: dodji
Date: Tue Jun  7 11:12:50 2011
New Revision: 174742

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174742
Log:
Fix PR debug/49130

gcc/c-family/

	* c-pretty-print.c (pp_c_integer_constant): Consider the canonical
	type when using pointer comparison to compare types.

gcc/testsuite/

	* g++.dg/debug/dwarf2/integer-typedef.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/integer-typedef.C
Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-pretty-print.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 dodji@seketeli.org 2011-06-07 22:21:43 UTC
After the discussions we've had elsewhere, I think DW_AT_name should
contain only the simple template name (with no template arguments) when
it refers to a template instantiation.  The debug info describing the
template argument should be enough [and less error-prone] for the
consumer to reconstruct the full template-id, if need be.

I have filed PR debug/49312 to track that task.
Comment 10 Dodji Seketeli 2011-06-07 22:26:23 UTC
(In reply to comment #1)
> I think it would be nicer if there were a DW_AT_mangled_name we could use
> instead because it's shorter.  This also would avoid inconsistencies.

Sorry, I don't understand this.  What would DW_AT_mangled_name contain that the DW_AT_MIPS_linkage_name doesn't already contain?  How would the content of that new attribute be shorter than DW_AT_MIPS_linkage_name, and how why would it make us avoid inconsistencies?
Comment 11 Jan Kratochvil 2011-07-08 12:33:19 UTC
I do not see any functionality problem from it, neither now and neither in the future.

(In reply to comment #7)
> But DW_AT_name really represents the name of the operator as written in the
> source code[2], with its template parameters replaced with their
> corresponding arguments.

Both variants of this code:

#include <string>
template <typename T>
void f () {}
//int main () { f<std::string> (); }
int main () { f<std::basic_string<char> > (); }

produce the same DWARF output:
    <2afa>   DW_AT_name        : f<std::basic_string<char> >

So one cannot say that one or the other matches the source code more.

One can only argue whether DWARF DW_AT_name should be compressed or not.
Comment 12 David Blaikie 2023-01-12 18:53:34 UTC
> Note that both DW_AT_name and DW_TAG_template_value_param are
> incorrect.  The demangler gets it right:
> 
>    void f<double>(S2<double, sizeof (double*)>)

Yeah, the problem here is that the /type/ is correctly `S2<double, 8ul>` - that's the same type no matter how it's written. But the mangling of `f` is distinct depending on how the expression is written...

I'm not really sure how we should encode that in DWARF - it'd be problematic to encode a different `S2` instantiation for this context compared to some other place that names the type differently - in terms of the debugger being able to treat them as the same type, match declarations and definitions, etc. I guess S2<double, sizeof (double*)> could be emitted as an alias/typedef of the underlying S2<double, 8ul>?

Or some other way to carry the mangle-equivalent details on the DW_TAG_template_*_parameter directly?

Though these expression template issues only apply to functions, yeah? Is there a need to deduplicate function definitions - generally the linker has already done this & the DWARF describes the function definition - I guess the issue here is that two different functions will have the same DW_AT_name & confuse the debugger/user if they're trying to call the functions in an expression evaluator, etc.