Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLDB misses the const method qualifier on Windows #117

Open
samolisov opened this issue Feb 4, 2020 · 13 comments
Open

LLDB misses the const method qualifier on Windows #117

samolisov opened this issue Feb 4, 2020 · 13 comments
Labels

Comments

@samolisov
Copy link
Contributor

I've tried LLDB built from the current release/10.x branch as well as from master.

On Windows, I'm using Clang++ to build a simple demo program.

#include <vector>

int main() {
    std::vector<int> v = {1, 2, 3};
    auto s = v.size();
    return 0;
}

Or

#include <vector>

template class std::vector<int>;

int main() {
    std::vector<int> v = {1, 2, 3};
    return 0;
}

I've see that the method

Summary: a.exe`public: unsigned __int64 __cdecl std::vector<int,class std::allocator<int> >::size(void)const  at vector:1446

is found in the output of

image lookup -n size

But when I put a breakpoint after the vector v definition and try do

e v.size()

or

p v.size()

I get only the following error:

(lldb) e v.size()
error: Couldn't lookup symbols:
  unsigned __int64 std::vector<int,std::allocator<int> >::size(void)

I see the const qualifier next to the method declaration in the output of

image lookup -n size

So, I tried to declare my vector also as const:

#include <vector>

int main() {
    const std::vector<int> v = {1, 2, 3};
    auto s = v.size();
    return 0;
}

Now LLDB is able to lookup the method but what I get is only the following error:

(lldb) p v.size()
error: <user expression 0>:1:1: 'this' argument to member function 'size' has type 'const std::vector<int,std::allocator<int> >', but
function is not marked const
v.size()
^
note: 'size' declared here

But I'm sure this in my vector is marked as const:

    const std::vector<int> v = {1, 2, 3};

I tried on Linux and LLDB works fine there, I get the right result: 3.

@dcci
Copy link
Member

dcci commented Feb 4, 2020

@Teemperor knows a lot about standard library functions evaluation, so maybe he has an idea of what's going wrong here.

@Teemperor
Copy link
Collaborator

The error error: <user expression 0>:1:1: 'this' argument to member function 'size' has type 'const std::vector<int,std::allocator<int> >', but function is not marked const tells you that your vector variable (which is the this for the function) is indeed const but that the size() function is not marked as const.

I assume that on Windows, Clang is emitting PDB (?) and LLDB's PDB parser is currently not able to create member functions marked as const (at least that's what I see in the code). Maybe take that with a grain of salt as I never touched the PDB code in LLDB before.

The reason why you see the const in image lookup -n size should be because size is a const-qualified function. image lookup -n size does not actually parse the debug information (like PDB) but just looks at the symbols, so that's why LLDB can understand it here but not in the expr command that parses the full debug information.

The error: Couldn't lookup symbols: error is probably caused by the fact that size() is getting forcibly inlined on your system, meaning there is no size function LLDB could call. I'm not sure what standard library you are using but if you are using a recent libc++ implementation then this should actually work (at least on macOS and Linux it works).

FWIW, vector's size method (and STL methods in general) are really weird corner cases. If you just want to look at a STL container just doing a simple p v will give you a summary of its contents in a readable form.

@samolisov
Copy link
Contributor Author

samolisov commented Feb 4, 2020

@Teemperor thank you for the comment. Yes, this is a PDB file generated by Clang. I think the vector's size method is not inlined, otherwise LLDB says about it and the function is not present in 'image lookup'. If I compile using MSVC, it inlines size() even in debug (and I have no idea how to disable it) and LLDB says about it. I believe LLDB looks for vector::size() const but because the vector variable is not const, it is not able to match the method.

I use the STL provided by Microsoft.

@Teemperor
Copy link
Collaborator

I can't really help with anything related to PDB or Microsoft's standard library. I guess @sstamenova maybe knows more about the state of LLDB with PDB (I'm not sure if she's active on GitHub though). I wasn't even aware that Clang supports Microsoft's standard library.

But anyway, It shouldn't matter if your vector is const or not, the problem is rather that your size() method isn't marked as const. The const-qualifier is also getting mangled so that could lead to looking up the wrong symbol in the end (IIRC PDB is actually using the AST it creates to build the mangled name)?

As you already built your own LLDB, you could try changing the , 0, to a , 1, in this line and see if that allows you to call size() (or at least produce a more help full error).

@samolisov
Copy link
Contributor Author

I've checked the vector file and I'm sure the method vector::size() is marked as const:

    _NODISCARD size_type size() const noexcept

I put 1 instead of 0, but unfortunately see no changes.

p v

also works a bit strange, I see the following results after the line where v has been initialized:

(lldb) p v
(std::vector<int,std::allocator<int> >) $0 = size=0 {}

or

(lldb) p v
(const std::vector<int,std::allocator<int> >) $0 = size=0 {}

@Teemperor
Copy link
Collaborator

I meant that the internal representation of the size function is not marked as const. LLDB's PDB parser should build this representation from PDB and what's happening is that it fails to mark the function as 'const' in the internal representation (as that doesn't seem to be implemented). The change I suggested should in theory mark all functions as const which should have at least fixed this call.

I don't think LLDB supports printing the std::vector from Microsoft's STL so I assume that's why you see an empty std::vector. But as said, I'm not sure what's the state of LLDB on Windows with Microsoft's STL.

@samolisov
Copy link
Contributor Author

samolisov commented Feb 6, 2020

@Teemperor I see there are two folders inside SymbolFile: PDB and NativePDB. I'm not sure, but I assume, PDB means work with Microsoft's DIA API. And that code already contains (PDB/PDBASTParser.cpp):

    if (func_sig->isConstType())
      type_quals |= clang::Qualifiers::Const;
    if (func_sig->isVolatileType())
      type_quals |= clang::Qualifiers::Volatile;
    auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
    CompilerType func_sig_ast_type =
        m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
                                 arg_list.size(), is_variadic, type_quals, cc);

I've changed type_quals to 1 and now get the following error regardless the v variable is marked as const:

error: Couldn't lookup symbols:
  unsigned __int64 std::vector<int,std::allocator<int> >::size(void) const

(So, here is the const marker). But it is strange since there is the similar (but with _cdecl) entry in the image lookup -n size:

 Summary: a.exe`public: unsigned __int64 __cdecl std::vector<int,class std::allocator<int> >::size(void)const  at vector:1446        Address: a.exe[0x000000014004dc20] (a.exe..text + 314400

@samolisov
Copy link
Contributor Author

samolisov commented Feb 6, 2020

@Teemperor If I right get the idea, this is a problem in the PDB file generated by Clang. But as my previous experiment show, LLDB is also not able to lookup the right symbol even if we force it to "understand" const qualifier.

@samolisov
Copy link
Contributor Author

Also, I don't understand why LLDB shows the following error when it analyses the code and PDB generated by MSVC:

(lldb) p v.size()
error: warning: warning: inline function 'std::vector<int,std::allocator<int> >::size' is not defined
<user expression 0>:1:3: used here
v.size()
  ^

error: Couldn't lookup symbols:
  unsigned __int64 std::vector<int,std::allocator<int> >::size(void) const

But I see in the generated assembly file, the method size() is not inlined:

...
    lea rcx, QWORD PTR v$[rsp]
    call    ?size@?$vector@HV?$allocator@H@std@@@std@@QEBA_KXZ ; std::vector<int,std::allocator<int> >::size
...

?size@?$vector@HV?$allocator@H@std@@@std@@QEBA_KXZ PROC ; std::vector<int,std::allocator<int> >::size, COMDAT
; File C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.22.27905\include\vector
; Line 1446
$LN3:
...
    ret 0
?size@?$vector@HV?$allocator@H@std@@@std@@QEBA_KXZ ENDP ; std::vector<int,std::allocator<int> >::size

@dwblaikie
Copy link
Collaborator

@rnk, in case he's got thoughts here

@rnk
Copy link
Collaborator

rnk commented Feb 10, 2020

Punt to @amccarth-google

@amccarth-google
Copy link
Collaborator

Nothing obvious comes to immediately to mind. I'll have to dig in a little to see what's going on. This is on my radar to investigate, but it's not my first priority right now.

The first step would be to try to determine whether problem is in the debug info generated by clang or in lldb's interpretation of it. Perhaps some poking about with llvm_pdbdump can yield some clues.

Are you linking the standard library statically or dynamically? If the latter, I wonder if there's conflicting debug info in the library's PDB compared to the one for your executable.

@RKSimon RKSimon added the lldb label Apr 12, 2022
@llvmbot
Copy link
Member

llvmbot commented Apr 12, 2022

@llvm/issue-subscribers-lldb

mmitche pushed a commit to mmitche/llvm-project that referenced this issue Aug 3, 2022
…604.1 (llvm#117)

[release/11.x] Update dependencies from dotnet/arcade
searlmc1 referenced this issue in ROCm/llvm-project Nov 27, 2023
…2023.07.27

Promote develop branch (as of 7ea6313) to mainline
mjklemm pushed a commit to mjklemm/llvm-project that referenced this issue Jul 16, 2024
[OpenMP] Fix use_device_ptr(addr) mappings for Fortran Pointer types

Fixes test in https://ontrack-internal.amd.com/browse/SWDEV-471469.
This fix also depends on @agozillon patch llvm#96265.
RevySR pushed a commit to revyos/llvm-project that referenced this issue Jul 27, 2024
…policy (llvm#117)

* [Clang][XTHeadVector] make wrappers default to TAMU policy

* [Clang][XTHeadVector] fix wrapper tests for vector-floating-conv (TAMU)

* [Clang][XTHeadVector] fix wrapper tests for vector-integer-compare (TAMU)

* [Clang][XTHeadVector] fix wrapper tests for vector-mask-logical (TAMU)

* [Clang][XTHeadVector] fix wrapper tests for vector-permutation (TAMU)

* [Clang][XTHeadVector] fix `HasMaskedOffOperand` of `th_vslidedown`

* [Clang][XTHeadVector] fix wrapper tests for vector-single-width-averaging (TAMU)

* [Clang][XTHeadVector] fix wrapper tests for `vsmul` (TAMU)

* [Clang][XTHeadVector] fix wrapper tests for vector-single-width-with-saturation-add (TAMU)

* [Clang][XTHeadVector] make wrappers for vector-reduction defaults to TUM policy

* [Clang][XTHeadVector] fix wrapper tests for vector-reduction (TUMU)

* [Clang][XTHeadVector] fix wrapper tests for vector-floating (TAMU)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants