This is an archive of the discontinued LLVM Phabricator instance.

[IRForTarget] Strenghten handling of alternate mangling.
ClosedPublic

Authored by sivachandra on Apr 6 2015, 2:07 PM.

Details

Summary

This fixes an issue with GCC generated binaries wherein an expression
with method invocations on std::string variables was failing. Such use
cases are tested in TestSTL (albeit, in a test marked with
@unittest2.expectedFailure because of other reasons).

The reason for this particular failure with GCC is that the generated
DWARF for std::basic_string<...> is incomplete, which makes clang not
to use the alternate mangling scheme. GCC correctly generates the name
of basic_string<...>:

DW_AT_name "basic_string<char, std::char_traits<char>, std::allocator<char> >"

It also lists the template parameters of basic_string correctly:

DW_TAG_template_type_parameter

DW_AT_name                  "_CharT"
DW_AT_type                  <0x0000009c>

DW_TAG_template_type_parameter

DW_AT_name                  "_Traits"
DW_AT_type                  <0x00000609>

DW_TAG_template_type_parameter

DW_AT_name                  "_Alloc"
DW_AT_type                  <0x000007fb>

However, it does not list the template parameters of std::char_traits<>.
This makes Clang feel (while parsing the expression) that the string
variable is not actually a basic_string instance, and consequently does
not use the alternate mangling scheme.

Diff Detail

Event Timeline

sivachandra updated this revision to Diff 23291.Apr 6 2015, 2:07 PM
sivachandra retitled this revision from to [IRForTarget] Strenghten handling of alternate mangling..
sivachandra updated this object.
sivachandra edited the test plan for this revision. (Show Details)
sivachandra added reviewers: clayborg, spyffe.
sivachandra added a subscriber: Unknown Object (MLST).
clayborg accepted this revision.Apr 6 2015, 3:09 PM
clayborg edited edge metadata.

I'll OK this on the condition that Sean Callanan OKs this. Sean?

This revision is now accepted and ready to land.Apr 6 2015, 3:09 PM
zturner added a subscriber: zturner.Apr 6 2015, 3:15 PM

Is it possible to do away with the hardcoded mangled name? I really
dislike seeing this kind of thing. Not only because it doesn't work with
all ABIs, but just in general it's very gross for the debugger to have
exceptions for specific mangled names. Why is this necessary, and is there
any way to get rid of it?

If it is necessary, can we at least move it to somewhere more appropriate
like the Mangled class and provide some kind of generic method like
Mangled::GetAlternateMangling()?

On Mon, Apr 6, 2015 at 3:32 PM, Sean Callanan <scallanan@apple.com> wrote:

I like this; we could have the CXXLanguageRuntime return a list of
“candidate” remangled names if you can’t find a given one, and then try
those.
The function would have the signature

size_t
CXXLanguageRuntime::GetAlternateManglings(ConstString mangled_name,
std::vector<ConstString> &alternate_names);

What do you folks think?

This sounds good. I will move the meat of this change into CPPLanguageRuntime.

A question: why would there be more than one alternate candidate for a given mangled name? There would either be a full mangling (the original) or a compressed mangling (the alternate).

[There could be a case where the compressed name is the original and the full name is the alternate. But, this case would mean that the clang generated name (compressed name) was not found in the target. That is scary because it could mean that clang compiled code cannot be linked with code generated by other compilers.]

Sorry for the follow up. Is it more meaningful this way:

class CPPLanguageRuntime 
{
public:
    ...
    virtual size_t GetAlternateManglings(const ConstString mangled, std::vector<ConstString> alternates) = 0;
    ...
};

class ItaniumABILanguageRuntime : public lldb_private::CPPLanguageRuntime
{
public:
    ...
    virtual size_t GetAlternateManglings(const ConstString mangled, std::vector<ConstString> alternates);
    ...
};
spyffe edited edge metadata.Apr 7 2015, 10:30 AM

Yes, I think that’s the right way to do it.

Sean

Siva,

two things:

the reason I prefer to have it return a vector is that we could have a variety of problems, e.g. missing “const” in the debug info, and I don’t want to have special-casing everywhere for each one.
I just noticed that in your suggestion ("Is it more meaningful this way”) you dropped the reference off the std::vector<ConstString> – it should definitely be passed in by reference.

Sean

sivachandra updated this revision to Diff 23376.Apr 7 2015, 3:37 PM
sivachandra edited edge metadata.

Modify according to suggestions from spyffe.

Can you check that this change fix TestCallStdStringFunction with g++ on Linux x86_64? I think it is failing with this or with a closely related issue.

By the way, seems this only fixes the case of std::string even though it
will continue to exist for any type with an unnamed template parameter..
Certainly std::string is the most important example, but I just want to
mention that the issue isn't that gcc produces alternate manglings, it's
that we build a clang AST out of incomplete DWARF (since gcc doesn't
produce complete debug info for unnamed template parameters) and the clang
AST resolves to a different mangling.

The hack seems ok to get the important case of std::string working, but
eventually maybe we should look for a real fix (perhaps asking clang to
parse the expression in the DW_AT_name)

On Thu, Apr 9, 2015 at 3:03 AM, Zachary Turner <zturner@google.com> wrote:

By the way, seems this only fixes the case of std::string even though it
will continue to exist for any type with an unnamed template parameter..
Certainly std::string is the most important example, but I just want to
mention that the issue isn't that gcc produces alternate manglings, it's
that we build a clang AST out of incomplete DWARF (since gcc doesn't produce
complete debug info for unnamed template parameters) and the clang AST
resolves to a different mangling.

Agreed. This was a low hanging fruit for me as the "work around" for std::basic_string was already in place. I only made the matching prefix complete.

Even things like invocation of std::map<std::string, int>::size are still broken as clang tries to demangle std::map<std::basic_string<...>, int, ...>::size and since the debug info for some of the template params is missing, it ends up with the uncompressed mangling. A point to note here is that GCC emits the compressed mangled name in the DWARF, but that is not read at all by LLDB. May be we can make clang use that name instead of generating a mangled name itself. Just a may be; I will look into fixing this thoroughly next.

On Thu, Apr 9, 2015 at 2:35 AM, Tamas Berghammer <tberghammer@google.com> wrote:

Can you check that this change fix TestCallStdStringFunction with g++ on Linux x86_64? I think it is failing with this or with a closely related issue.

Yes. This fixes that test as well.

spyffe accepted this revision.Apr 9 2015, 9:39 AM
spyffe edited edge metadata.

This patch looks good to me, thanks Siva!

sivachandra edited edge metadata.

Rebase.

sivachandra closed this revision.Apr 9 2015, 11:51 AM