Author: Nerixyz Date: 2026-06-08T19:47:26Z New Revision: fffc591d831ace2fb4da53c5bdb7c44dac810ccb
URL: https://github.com/llvm/llvm-project/commit/fffc591d831ace2fb4da53c5bdb7c44dac810ccb DIFF: https://github.com/llvm/llvm-project/commit/fffc591d831ace2fb4da53c5bdb7c44dac810ccb.diff LOG: [lldb][NativePDB] Handle invalid type references gracefully (#202371) Incrementally linked PDBs can contain semantically incorrect references to types from the symbol streams and the IPI stream. I can't reproduce it reliably, but as mentioned in #200452, at some point the references become incorrect. We should not crash if we receive such PDBs as input. Here I noticed two issues: 1. `CVTagRecord` requires the passed type to be a type record (union/struct/class). We should check that this is the case with `IsTagRecord`. 2. After casting the return of `GetOrCreateClangType`, check that it's the expected type (not null). I added a test for both cases. Added: lldb/test/Shell/SymbolFile/NativePDB/invalid-type-refs.yaml Modified: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp index e1cdfca57e79e..673bd2826b455 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp @@ -1027,13 +1027,18 @@ clang::FunctionDecl *PdbAstBuilderClang::CreateFunctionDecl( TypeIndex class_index = func_record.getClassType(); CVType parent_cvt = index.tpi().getType(class_index); + if (!IsTagRecord(parent_cvt)) + return nullptr; TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag(); // If it's a forward reference, try to get the real TypeIndex. if (tag_record.isForwardRef()) { llvm::Expected<TypeIndex> eti = index.tpi().findFullDeclForForwardRef(class_index); if (eti) { - tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag(); + CVType resolved_tag_record = index.tpi().getType(*eti); + if (!IsTagRecord(resolved_tag_record)) + return nullptr; + tag_record = CVTagRecord::create(resolved_tag_record).asTag(); } else { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), eti.takeError(), "failed to find full decl for forward ref: {0}"); @@ -1229,6 +1234,8 @@ PdbAstBuilderClang::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { const clang::FunctionProtoType *func_type = llvm::dyn_cast<clang::FunctionProtoType>(qt); + if (!func_type) + return nullptr; CompilerType func_ct = ToCompilerType(qt); diff --git a/lldb/test/Shell/SymbolFile/NativePDB/invalid-type-refs.yaml b/lldb/test/Shell/SymbolFile/NativePDB/invalid-type-refs.yaml new file mode 100644 index 0000000000000..341abd32eb838 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/invalid-type-refs.yaml @@ -0,0 +1,221 @@ +# Check that semantically incorrect type references are handled without errors/crashes. + +# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t +# RUN: lldb-test symbols %t | FileCheck %s + +# CHECK: CompileUnit +# CHECK-NEXT: Function{{.*}}, demangled = main +# CHECK-NEXT: Block{{.*}}, ranges = [0x00000fff-0x0000101b) +# CHECK-NEXT: Function{{.*}}, demangled = AStruct::a_method +# CHECK-NEXT: Block{{.*}}, ranges = [0x0000101f-0x0000102b) + +# This was compiled with clang-cl from + +# > clang-cl main.cpp /GS- /GR- /Z7 /link /nodefaultlib /entry:main +# > cat main.cpp +# struct AStruct { +# int a_method() { return 42; } +# }; +# int main() { +# AStruct a; +# return a.a_method(); +# } + +# The output was trimmed to only include necessary parts. +# Changes to references are marked with "CHANGED:". + +--- +PdbStream: + Features: [ VC140 ] +DbiStream: + MachineType: Amd64 + Modules: + - Module: 'C:\Users\johannes\AppData\Local\Temp\main-b7a866.obj' + SourceFiles: + - 'F:\Dev\dummy\invalid-refs\main.cpp' + Modi: + Records: + - Kind: S_OBJNAME + ObjNameSym: + Signature: 0 + ObjectName: 'C:\Users\johannes\AppData\Local\Temp\main-b7a866.obj' + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: X64 + FrontendMajor: 22 + FrontendMinor: 1 + FrontendBuild: 4 + FrontendQFE: 0 + BackendMajor: 22014 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 22.1.4 (https://github.com/llvm/llvm-project 35990504507d79e0b9deb809c8ee5e1b34ceef20)' + - Kind: S_GPROC32 + ProcSym: + PtrEnd: 300 + CodeSize: 28 + DbgStart: 0 + DbgEnd: 0 + # CHANGED: Should be 4097 (LF_PROCEDURE). Changed to 4099 (LF_POINTER). + FunctionType: 4099 + Segment: 1 + Flags: [ IsNoInline, HasOptimizedDebugInfo ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 40 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ SafeBuffers ] + - Kind: S_LOCAL + LocalSym: + Type: 4102 + Flags: [ ] + VarName: a + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 35 + Range: + OffsetStart: 12 + ISectStart: 1 + Range: 16 + Gaps: [] + - Kind: S_END + ScopeEndSym: {} + - Kind: S_BUILDINFO + BuildInfoSym: + BuildId: 4105 + - Kind: S_GPROC32 + ProcSym: + PtrEnd: 436 + CodeSize: 12 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4100 + Offset: 32 + Segment: 1 + Flags: [ IsNoInline, HasOptimizedDebugInfo ] + DisplayName: 'AStruct::a_method' + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 8 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ SafeBuffers ] + - Kind: S_LOCAL + LocalSym: + Type: 4103 + Flags: [ IsParameter ] + VarName: this + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 0 + Range: + OffsetStart: 37 + ISectStart: 1 + Range: 7 + Gaps: [] + - Kind: S_END + ScopeEndSym: {} + SectionHeaders: + - Name: .text + VirtualSize: 44 + VirtualAddress: 4096 + SizeOfRawData: 512 + PointerToRawData: 1024 + Characteristics: 1610612768 + - Name: .rdata + VirtualSize: 104 + VirtualAddress: 8192 + SizeOfRawData: 512 + PointerToRawData: 1536 + Characteristics: 1073741888 + - Name: .pdata + VirtualSize: 24 + VirtualAddress: 12288 + SizeOfRawData: 512 + PointerToRawData: 2048 + Characteristics: 1073741888 +TpiStream: + Records: + # 4096 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] + # 4097 + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + # 4098 + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: AStruct + UniqueName: '.?AUAStruct@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + # 4099 + - Kind: LF_POINTER + Pointer: + ReferentType: 4098 + Attrs: 66572 + # 4100 + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 116 + # CHANGED: Should be 4098 (LF_STRUCTURE). Changed to 4097 (LF_PROCEDURE). + ClassType: 4097 + ThisType: 4099 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + ThisPointerAdjustment: 0 + # 4101 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_ONEMETHOD + OneMethod: + Type: 4100 + Attrs: 3 + VFTableOffset: -1 + Name: a_method + # 4102 + - Kind: LF_STRUCTURE + Class: + MemberCount: 1 + Options: [ None, HasUniqueName ] + FieldList: 4101 + Name: AStruct + UniqueName: '.?AUAStruct@@' + DerivationList: 0 + VTableShape: 0 + Size: 1 + # 4103 + - Kind: LF_POINTER + Pointer: + ReferentType: 4098 + Attrs: 65548 +PublicsStream: + Records: + - Kind: S_PUB32 + PublicSym32: + Flags: [ Function ] + Segment: 1 + Name: main +... _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
