<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/114068>114068</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Stack overflow / segfault in `getASTRecordLayout` inspecting variables for rust enum values with matching field names
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
LloydW93
</td>
</tr>
</table>
<pre>
Potentially similar issues:
https://github.com/llvm/llvm-project/issues/64628
https://github.com/llvm/llvm-project/issues/43604
https://github.com/llvm/llvm-project/issues/63667
https://github.com/llvm/llvm-project/issues/66335
https://github.com/llvm/llvm-project/issues/53490
Probably related issue/fix:
https://github.com/llvm/llvm-project/pull/68300
https://github.com/llvm/llvm-project/issues/68135
When debugging the following rust code using rust-lldb (a script that loads some extra formatters):
```
use std::collections::HashMap;
struct ValueType {}
enum OuterEnum {
ValueType(ValueType),
}
fn main() {
let mut map = HashMap::<String, OuterEnum>::new();
map.insert("Host".into(), OuterEnum::ValueType(ValueType{}));
}
```
`frame variable` after `map` has been declared results in a stack overflow, followed by a segfault. The diagnostic.log is empty.
The top/tail of the stack:
```
* thread #1, name = 'lldb-20', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x7fffff7fee78)
* frame #0: 0x00007ffff3d5c2f9 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 89
frame #1: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #2: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #3: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #4: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #5: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #6: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #7: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #8: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #9: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
...
frame #10568: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #10569: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #10570: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #10571: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #10572: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #10573: 0x00007ffff3d61c75 libclang-cpp.so.20.0`___lldb_unnamed_symbol54200 + 261
frame #10574: 0x00007ffff3d5caa2 libclang-cpp.so.20.0`clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const + 2050
frame #10575: 0x00007ffff381b511 libclang-cpp.so.20.0`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 2017
frame #10576: 0x00007ffff381ce83 libclang-cpp.so.20.0`clang::ASTContext::getTypeInfo(clang::Type const*) const + 179
frame #10577: 0x00007ffff794f2d7 liblldb-20.so.1`___lldb_unnamed_symbol28450 + 151
frame #10578: 0x00007ffff73f69ea liblldb-20.so.1`___lldb_unnamed_symbol14339 + 410
frame #10579: 0x00007ffff73f6a7d liblldb-20.so.1`___lldb_unnamed_symbol14340 + 13
frame #10580: 0x00007ffff71785c8 liblldb-20.so.1`lldb::SBType::GetByteSize() + 232
frame #10581: 0x00007ffff727caad liblldb-20.so.1`___lldb_unnamed_symbol9509 + 93
frame #10582: 0x00007fffe98d8fc5 libpython3.12.so.1.0`cfunction_vectorcall_O(func=0x00007fffe5219ad0, args=0x00007fffe5995268, nargsf=<unavailable>, kwnames=0x0000000000000000) at methodobject.c:509:24
frame #10583: 0x00007fffe987fafc libpython3.12.so.1.0`PyObject_Vectorcall [inlined] _PyObject_VectorcallTstate(kwnames=0x0000000000000000, nargsf=9223372036854775809, args=0x00007fffe5995268, callable=0x00007fffe5219ad0, tstate=0x00007fffe9f9cf68) at pycore_call.h:92:11
```
The loop starts when the synthetic lookup function calls GetByteSize() on `map.base.table`'s type (`<String, OuterEnum>`). When inspecting the debug symbols, we can see there appears to be recursion:
```
(lldb) image lookup -A -t ValueType
1 match found in /path/to/test-c9fdb3ba00c12481:
id = {0x7fffff0000001912}, name = "ValueType", qualified = "test::OuterEnum::ValueType", byte-size = 0, compiler_type = "struct ValueType {
private:
test::OuterEnum::ValueType __0;
}"
```
This is obviously circular and incorrect - and though I'm not sure if that's the symbol file or the interpretation, I'm hoping there's something that can be done to handle that better...
If we rename the Enum value's field to `ValueType1`, then everything works:
```
(lldb) image lookup -A -t ValueType
1 match found in /path/to/test-c9fdb3ba00c12481:
id = {0x7fffff0000001912}, name = "ValueType", qualified = "test::OuterEnum::ValueType", byte-size = 0, compiler_type = "struct ValueType {
private:
test::ValueType1 __0;
}"
````
I've reproduced this with lldb-18, lldb-19.1, and nightly.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWV1v2zrS_jXMzSACRX1f-MJJmp4C50WLN0XPpUFRI4tbStSSlFOfX78gZTt2avd0mz3ZXGxgOKI4nI9nHpGeEbdWrgfEBcluSHZ3xSfXabP4Xelt80eVXNW62S4-aYeDk1ypLVjZS8UNSGsntCRZEnpH6LJzbgwjdk_Y_Vq6bqojoXvC7pXa7P9dj0b_A4Uj7H63nt3nac7KlypJk5ymL_YkyfPixUryJMleqiRL0orOSubvT0bXvFZbMKi4w2aGn7D7Vn779RyMk1Le5TKh9MVxl_E-7vn7jw4HaLCe1ms5rMF1CK1WSj_6kZmsA6EbhMnux9dKNTUQVnKwwsjRgeu4A6V5Y8HqHgG_OcOh1abnzqGxhFWH4ElOd58wnCyCdY2fTpZCK4XCST3Y-cZv3Hb_x0eS3Bx7bJ2ZhIMvXE34eTsikOKGFHfHIjhMPXycHJp3_soLhPtPiwgrj64rwm53608VtQP0XA6ElYRVR3oAQKGDfnLQ8xFIcgcHZ5fhc_vgjBzWhN0-OUKSd_P0gI-zykNoXmPPx0gOFo0Lk-w3bR1hLJKD0zvxU21e1fmIZkT8gicTT6Gd5uBwszW8R9hwI3mtkOQUeOvQAMlpz0c_7riFGgNhhOIGGzBoJ-UsyAE4WMfFV9AbNK3Sj97ZmUrYQL3187hu-aRcBJ87hEby9aCtkyJSeg3SAvaj20bHXnk5p0fC7h2XCnQbCBrsXKIUYUtwnUHeAGFJ7L0YfFw-R4QVnr3XjBJW-Bnr9AgGudVDEPC7LFfw8OH9w7v3X0iyBN40Bq2FQYdUj9iA06Br_2D5pyAEtJfyC-i3ovV_RYtYhKTtEuwdmyEmLKGzKKWUBvGkyQRrK1CyFooP62sxjpHVEaORDy3cmxO-fPh8qweH39w8XqNbPnz-fxTaNL_zrZ48e47k55k7FAqEHjyjlp7L4RoIu4GyeqLgwb_4O__yWBTZJf9Wq5UHdjUNHutmZbd9rVWWMkqDDZbHZ4ywMyBwzv4bIDCa0TMeJq8BQ_rmYcheA4b8zcNQvAYM5ZuHofqbYIii6NxORLP87WPivfy7cHluqDh3eLw5OIpXOUK8obd_jHgvX-Uo8Ybe_nHivfzuSCnjOovjX_PS_-b9MLT6Qz-qUxdDgXDJubi44Nx3R1EZCyyTlzn3047FxdlfZDQrnh9ARZW2rCm8X7vftd6r-CJ9WJlmM33i7BJ9nu-1RdLmFfKfthGnSVIFG2m8T_6JgefbpDfAi-bfMZDugkjOx1A-3yCLuCgzUZ4x4YdzQh5uQuUUrt-ju9k6fJB_4r7084RJ2AV7z7e6ghWC858PqcrobKJKziBWPtvgsCqbshVh6xi3rtNDEsUsWJjp2E5DKKNXGxROG8GVWn30tco0CJLcHWnKWFzxhvpSiJu1fTZZVRnLy7mCMmvbkuSOJLfTwDdcqlAjJu_87NdHH8zT6uM_Dx530KPrdDOXTZEgyTKjngcsvYBo8l3IRctbcSnkT9uPQfXqyyFiINmNHJQcsCHZHazOiHy2jjuf4R8HcBR-xViSFIwmeZmlRZGVtPpL7LylGawLyLvZjZPpqq1Em5c79Mat0AZXXlPUkWRZeUbE8Q_KeV84K61HXysbZ-Gxw2GunbeD69BJ4ae_TiPsyRL8tPA99X1pHDoAUc0tRm7XHCCssOBC_4WVfnyx5eFlqwhCp0kOdkTh9q2m0HiC-SGwfuEjguADWEQ_bxB8yc2N9UV3jWBQTMZKPVyu_svwSLMKZM_XuI_yegnXRz2jWTiGnjvRQaunoQE5AGH3I3cdYfdO-y-07lpUbVMnNadUxCwNj_q8WjZzT6G42Zf8M2HiKmah-3LSeGBHjRrm5_45cSVbic1ewFubt5_LLZ6wst46vLbyz1l1oJDQ_SgVmtWckFnh2UZZcH00chMotwsF_to2rFb0pJXE2A_pJy1IC7reSD1ZtQUhjZgUN8AD1EIbg8LBdRi7Tk_rDj4QVvSh02IngyDb0FqciRao62kCrVQI2oRbcnBoRoOOewp7JGYdnR53FDMY1lvtd6D5HneBYzVCowf0zOr40Cicp2p0Ds2hFpm_P7SemQZDQr3h0FfceHCC-laiCo0hktMDZHFg_q2XHwA3aLazB4_afH1qyf-Pxv85GgMcMfkpDz_B3VP6ehJtfL5Ho5tJoGeotPAoXQfhQI_Dzj5fVlFoMnoeD3LdOXXawrxqFklTJRW_wkVcJJTFaczoVbcQSRbzpmoZLVrapFXF67jg2JZZUVeZyK_kglGWxpRVcUYZpRHPyqJkWApMaULjmKQUey5VpNSmj7RZX4U-_yKOU5qXV4rXqOz-lZFZhHcC9bS2JKVKWmef1jnpFC4eTvq3nkaHlm2gVU7PVAQ5Pd7U991jC6028_sDPDwqOwQDW73w_NSEo_dqMmrx6681dhFvFuxfAQAA___nxyg2">