Skip to content

Commit e08d8e3

Browse files
authored
[LLDB][PDB] Run UDT layout test with native PDB too (#159769)
This test was failing with the native plugin due to two reasons: 1. The static `C::abc` was printed as `(int) ::C::abc = 123` 2. The order of the base classes of [`C` (`List::Value`)](https://github.com/llvm/llvm-project/blob/b7e4edca3d56ec87f719c202f5397b245595f7cc/lldb/test/Shell/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp#L30) is different between DIA and the native plugin. I don't know how the order in the DIA plugin is determined - it prints `B<0>`, `B<1>`, `B<2>`, `B<3>`, `A`. The native plugin follows the order of the bases in memory and prints `B<2>`, `B<3>`, `A`, `B<0>`, `B<1>` (last three are the virtual bases). <details><summary>Class layout of C</summary> ``` class C size(88): +--- 0 | +--- (base class B<2>) 0 | | {vbptr} 8 | | _a 9. | | _b (bitstart=3,nbits=6) 11 | | _c | +--- 15 | +--- (base class B<3>) 15 | | {vbptr} 23 | | _a 24. | | _b (bitstart=3,nbits=6) 26 | | _c | +--- | <alignment member> (size=2) 32 | _x 36 | _y 38 | _z | <alignment member> (size=1) | <alignment member> (size=2) +--- +--- (virtual base A) 40 | {vfptr} 48 | U _u | <alignment member> (size=4) +--- +--- (virtual base B<0>) 56 | {vbptr} 64 | _a 65. | _b (bitstart=3,nbits=6) 67 | _c +--- +--- (virtual base B<1>) 71 | {vbptr} 79 | _a 80. | _b (bitstart=3,nbits=6) 82 | _c +--- ``` </details> I split the tests for the plugins for better readability.
1 parent 86d767c commit e08d8e3

File tree

2 files changed

+130
-1
lines changed

2 files changed

+130
-1
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# REQUIRES: target-windows
2+
3+
# Test UDT layout reconstruction
4+
# RUN: split-file %s %t
5+
# RUN: %build --compiler=clang-cl -o %t.exe -- %t/main.cpp
6+
# RUN: %lldb -f %t.exe -s %t/commands.input 2>&1 | FileCheck %s
7+
8+
#--- main.cpp
9+
10+
// this is from the DIA plugin (UdtLayoutTest.cpp)
11+
struct A {
12+
explicit A(int u) { _u._u3 = u; }
13+
A(const A &) = default;
14+
virtual ~A() = default;
15+
16+
private:
17+
union U {
18+
char _u1;
19+
short _u2;
20+
int _u3;
21+
};
22+
23+
A::U _u;
24+
};
25+
26+
#pragma pack(push, 1)
27+
template <int I> struct B : public virtual A {
28+
B(char a, unsigned short b, int c) : A(a + b + c), _a(a), _b(b), _c(c) {}
29+
30+
private:
31+
char _a;
32+
unsigned short : 3;
33+
unsigned short _b : 6;
34+
unsigned short : 4;
35+
int _c;
36+
};
37+
#pragma pack(pop)
38+
39+
#pragma pack(push, 16)
40+
class C : private virtual B<0>, public virtual B<1>, private B<2>, public B<3> {
41+
public:
42+
C(char x, char y, char z)
43+
: A(x - y + z), B<0>(x, y, z), B<1>(x * 2, y * 2, z * 2),
44+
B<2>(x * 3, y * 3, z * 3), B<3>(x * 4, y * 4, z * 4), _x(x * 5),
45+
_y(y * 5), _z(z * 5) {}
46+
47+
static int abc;
48+
49+
private:
50+
int _x;
51+
short _y;
52+
char _z;
53+
};
54+
int C::abc = 123;
55+
#pragma pack(pop)
56+
57+
class List {
58+
public:
59+
List() = default;
60+
List(List *p, List *n, C v) : Prev(p), Next(n), Value(v) {}
61+
62+
private:
63+
List *Prev = nullptr;
64+
List *Next = nullptr;
65+
C Value{1, 2, 3};
66+
};
67+
68+
int main() {
69+
List ls[16];
70+
return 0; // break here
71+
}
72+
73+
#--- commands.input
74+
75+
settings set target.max-children-depth 10
76+
br set -p "break here"
77+
run
78+
target variable
79+
frame variable
80+
quit
81+
82+
# CHECK: (int) ::C::abc = 123
83+
84+
# CHECK: (List[16]) ls = {
85+
# CHECK: [15] = {
86+
# CHECK-NEXT: Prev = nullptr
87+
# CHECK-NEXT: Next = nullptr
88+
# CHECK-NEXT: Value = {
89+
# CHECK-NEXT: B<2> = {
90+
# CHECK-NEXT: A = {
91+
# CHECK-NEXT: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
92+
# CHECK-NEXT: }
93+
# CHECK-NEXT: _a = '\x03'
94+
# CHECK-NEXT: _b = 6
95+
# CHECK-NEXT: _c = 9
96+
# CHECK-NEXT: }
97+
# CHECK-NEXT: B<3> = {
98+
# CHECK-NEXT: A = {
99+
# CHECK-NEXT: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
100+
# CHECK-NEXT: }
101+
# CHECK-NEXT: _a = '\x04'
102+
# CHECK-NEXT: _b = 8
103+
# CHECK-NEXT: _c = 12
104+
# CHECK-NEXT: }
105+
# CHECK-NEXT: A = {
106+
# CHECK-NEXT: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
107+
# CHECK-NEXT: }
108+
# CHECK-NEXT: B<0> = {
109+
# CHECK-NEXT: A = {
110+
# CHECK-NEXT: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
111+
# CHECK-NEXT: }
112+
# CHECK-NEXT: _a = '\x01'
113+
# CHECK-NEXT: _b = 2
114+
# CHECK-NEXT: _c = 3
115+
# CHECK-NEXT: }
116+
# CHECK-NEXT: B<1> = {
117+
# CHECK-NEXT: A = {
118+
# CHECK-NEXT: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
119+
# CHECK-NEXT: }
120+
# CHECK-NEXT: _a = '\x02'
121+
# CHECK-NEXT: _b = 4
122+
# CHECK-NEXT: _c = 6
123+
# CHECK-NEXT: }
124+
# CHECK-NEXT: _x = 5
125+
# CHECK-NEXT: _y = 10
126+
# CHECK-NEXT: _z = '\x0f'
127+
# CHECK-NEXT: }
128+
# CHECK-NEXT: }
129+
# CHECK-NEXT: }

lldb/test/Shell/SymbolFile/PDB/udt-layout.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
REQUIRES: target-windows, lld
1+
REQUIRES: target-windows, lld, diasdk
22
RUN: %build --compiler=clang-cl --output=%t.exe %S/Inputs/UdtLayoutTest.cpp
33
RUN: %lldb -b -s %S/Inputs/UdtLayoutTest.script -- %t.exe | FileCheck %s
44

0 commit comments

Comments
 (0)