Skip to content

lldb test TestUniqueTypes4.py now fails on Windows #75936

Open
@DavidSpickett

Description

@DavidSpickett

llvm-project\lldb\test\API\lang\cpp\unique-types4\TestUniqueTypes4.py stopped working on Windows once dd95877 landed.

This patch also changed what the test looked for, so the fact that it was passing before doesn't mean as much as you'd think.

The problem now seems to be that for a program like the following:

namespace ns {

template <typename T> struct Foo {
  static T value;
};

template <class T> T Foo<T>::value = 99;

using FooDouble = Foo<double>;

} // namespace ns

ns::Foo<double> a;
ns::FooDouble f;

int main() {
  // Set breakpoint here
  return (int)a.value + (int)f.value;
}

When compiled with:

..\bin\clang++.exe main.cpp -o main.exe -fuse-ld=lld -gdwarf

(this results in there being DWARF info in main.exe, with an external PDB, this is expected and presumably supported because the test worked before)

LLDB on Windows cannot print the ::value member.

(lldb) expression ns::FooDouble::value
(ror: Couldn't look up symbols:or <Unknown>...
(ns::Foo<double>::value

(there is some text corruption due to a log message mixed in there)

On Linux it works as expected:

./bin/clang++ -target aarch64-linux-gnu-eabi /tmp/test.cpp -o /tmp/test.o -gdwarf
(lldb) expression ns::FooDouble::value
(double) $0 = 0

The DWARF info has one maybe significant change.

Do this to get the DWARF if you aren't on Windows:

$ ./bin/clang++ -target arm64-pc-windows-msvc /tmp/test.cpp -o /tmp/test.o -gdwarf -c

llvm-dwarfdump of both shows that "value" is described but Windows uses DW_TAG_member and Linux uses DW_TAG_variable. However, each has a following DW_TAG_variable for "value" also. So maybe this doesn't matter at all.

Windows:

0x0000005a:       DW_TAG_member
                    DW_AT_name  ("value")
                    DW_AT_type  (0x00000085 "double")
                    DW_AT_decl_file     ("/tmp/test.cpp")
                    DW_AT_decl_line     (4)
                    DW_AT_external      (true)
                    DW_AT_declaration   (true)
<...>
0x00000071:     DW_TAG_variable
                  DW_AT_specification   (0x0000005a "value")
                  DW_AT_location        (DW_OP_addr 0x0)
                  DW_AT_linkage_name    ("?value@?$Foo@N@ns@@2NA")

Linux:

0x0000003c:       DW_TAG_variable
                    DW_AT_name  ("value")
                    DW_AT_type  (0x00000057 "double")
                    DW_AT_decl_file     ("/tmp/test.cpp")
                    DW_AT_decl_line     (4)
                    DW_AT_external      (true)
                    DW_AT_declaration   (true)
<...>
0x0000004d:     DW_TAG_variable
                  DW_AT_specification   (0x0000003c "value")
                  DW_AT_location        (DW_OP_addrx 0x2)
                  DW_AT_linkage_name    ("_ZN2ns3FooIdE5valueE")

If I instead generate CodeView on Windows, it gets a bit further.

I wonder if perhaps the Windows build is treating this "value" as some constant that is never materialised, whereas Linux makes it a value we can easily read.

lldb can see information from the DWARF on Windows, just not the bit we want for this test:

(lldb) (lldb) p a
(ns::Foo<double>)  {}
(lldb) p f
(ns::FooDouble)  {}
(lldb) image lookup -t ns::FooDouble
Best match found in C:\Work\david.spickett\build\testprog\main.exe:
id = {0x00000066}, name = "ns::FooDouble", byte-size = 1, decl = main.cpp:9, compiler_type = "typedef ns::FooDouble"
     typedef 'ns::FooDouble': id = {0x00000048}, name = "Foo<double>", qualified = "ns::Foo<double>", byte-size = 1, decl = main.cpp:3, compiler_type = "template<> struct Foo<double> {
    static double value;
}"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions